home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 751-760 / 756 / popupmenu / source / startup.a < prev   
Text File  |  1995-03-18  |  60KB  |  2,396 lines

  1.         include     "All.i"
  2.         include     "exec/types.i"
  3.         include     "PopUp.i"
  4.  
  5.         xref        @PopUpMenu
  6.  
  7.         xdef        @QueTimer
  8.         xdef        @AbortTimer
  9.         xdef        PopUpSemaphore
  10.  
  11. ; @ before label means standard c function (D0-D1/A0-A1 destroyed etc)
  12. ; _ before label means ordinary variable
  13. ;   nothing before label means variable located in code segment
  14. ; uppercase labels means constants placed in code segment
  15. ;
  16.  
  17.         section     text,code
  18. ;    Make room for global data on stack
  19. ProgStart:    lea        -Globals_SIZEOF(SP),SP
  20.         move.l        SP,A4
  21.  
  22. ;    Clear all global data
  23.         move.l        SP,A0
  24.         move.w        #Globals_SIZEOF/2-1,D1
  25.         moveq.l     #0,D0
  26.  
  27. 1$        move.w        D0,(A0)+
  28.         dbra        D1,1$
  29.  
  30. ;    Move ExecBase to the data area. two reasons
  31. ;      1. Easy to reach when needed [MOVE.L    (A4),A6]
  32. ;      2. Faster if data area is in FAST RAM
  33.         move.l        (AbsExecBase).w,A6
  34.         move.l        A6,_ExecBase(A4)   ; Lets hope this is FAST RAM
  35.  
  36. ;    Get the address of our task
  37.         move.l        ThisTask(A6),A5  ; A5 = ThisTask
  38.  
  39. ; ------------------------------------------------------------------------------
  40. ;        moveq.l     #0,D0
  41.  
  42. ;    Started form CLI ?
  43.         tst.l        pr_CLI(A5)
  44.         bne        FromCLI        ; Yes
  45.  
  46. ;    Wait for startup message.
  47.         lea        pr_MsgPort(A5),A0
  48.         libcall     WaitPort        ; (A0=port)
  49.  
  50.         lea        pr_MsgPort(A5),A0
  51.         libcall     GetMsg        ; (A0=port)
  52.  
  53. ;
  54. FromCLI:    move.l        D0,_WBenchMsg(A4)
  55.  
  56. ;    Open Dos library
  57.         lea        DOSNAME(PC),A1
  58.         moveq.l     #KICK204,D0        ; Need version 2.04
  59.         libcall     OpenLibrary     ; (A1=libname,D0=version)
  60.  
  61.         move.l        D0,_DOSBase(A4)
  62.         beq        NoDos           ; No dos !!!?
  63.  
  64. ;    Clear the hotkey field
  65.         lea        DEFAULTHOTKEY(PC),A0
  66.         lea        _HotKeyString(A4),A1
  67. 1$        move.b        (A0)+,(A1)+
  68.         bne        1$
  69.  
  70. ;    Parse arguments
  71.         call        ParseArgs        ; ()
  72.  
  73. ; ------------------------------------------------------------------------------
  74.  
  75. ;  D0.b = Options
  76. ;  D1.b = CX_PRIORITY
  77. ;  _HotKeyString(A4) = HotKey
  78.  
  79. ;    Save the entered options
  80.         move.b        D0,_CxHandlerData+ssd_Options(A4)
  81.  
  82. ; -----------------------------------------------------------------------------
  83. ;    Create our broker
  84. ;    Set the broker priority
  85.         lea        BrokerData(PC),A2
  86.         move.b        D1,nb_Pri(A2)
  87.  
  88. ;    We need a port in the NewBroker structure
  89.         libcall     CreateMsgPort    ; ()
  90.  
  91.         move.l        D0,nb_Port(A2)
  92.         beq        NoBrokerPort
  93.  
  94. ;    Open Commodities library
  95.         lea        COMMODITYNAME(PC),A1
  96.         moveq.l     #KICK204,D0        ; Kick 2.04 needed here
  97.         libcall     OpenLibrary     ; (A1=libname,D0=version)
  98.  
  99.         move.l        D0,_CxBase(A4)
  100.         move.l        D0,CxBase           ; For the inputhandler
  101.         beq        NoCommodity
  102.  
  103.         move.l        D0,A6
  104.  
  105. ;    Start up the broker
  106.         move.l        A2,A0        ; A2 = BrokerData
  107.         moveq.l     #0,D0
  108.         libcall     CxBroker        ; (A0=nb,D0=error)
  109.  
  110.         move.l        D0,_PopUpBroker(A4)
  111.  
  112. ;    If we can't create the broker PopUpMenu is probably already running
  113.         beq        NoBroker
  114. ; -----------------------------------------------------------------------------
  115.  
  116. ;    PopUpMenu is not installed
  117. ;    Open needed libraries (All these are in ROM so they can be permanent)
  118. ;    Intuition
  119.         move.l        _ExecBase(A4),A6
  120.         lea        INTUITIONNAME(PC),A1
  121.         moveq.l     #KICK204,D0
  122.         libcall     OpenLibrary     ; (A1=libname,D0=version)
  123.  
  124.         move.l        D0,_IntuitionBase(A4)
  125.         move.l        D0,IBase         ; for the inputhandler
  126.         beq        NoIntuition
  127.  
  128. ;    Graphics
  129.         lea        GFXNAME(PC),A1
  130.         moveq.l     #KICK204,D0
  131.         libcall     OpenLibrary     ; (A1=libname,D0=version)
  132.  
  133.         move.l        D0,_GfxBase(A4)
  134.         beq        NoGraphics
  135.  
  136. ;    Layers
  137.         lea        LAYERSNAME(PC),A1
  138.         moveq        #KICK204,D0
  139.         libcall     OpenLibrary     ; (A1=libname,D0=version)
  140.  
  141.         move.l        D0,_LayersBase(A4)
  142.         beq        NoLayers
  143.  
  144. ; ------------------------------------------------------------------------------
  145. ;    We need a replyport for the intuimessages
  146.         libcall     CreateMsgPort    ; ()
  147.  
  148.         move.l        D0,_ReplyPort(A4)
  149.         beq        NoReplyPort
  150.  
  151. ; ------------------------------------------------------------------------------
  152. ;    We need the timer device
  153. ;    Create a port
  154.         libcall     CreateMsgPort    ; ()
  155.  
  156.         move.l        D0,_TimerPort(A4)
  157.         beq        NoTimerPort
  158.  
  159. ;    Create a IOStdReq
  160.         move.l        D0,A0
  161.         moveq.l     #IOTV_SIZE,D0
  162.         libcall     CreateIORequest    ; (A0=port,D0=size)
  163.  
  164.         move.l        D0,_TimerReqBlock(A4)
  165.         beq        NoTimerIOStdReq
  166.  
  167. ;    Open the timer device, (UNIT_VBLANK)
  168.         lea        TIMERNAME(PC),A0
  169.         move.l        D0,A1
  170.         moveq.l     #UNIT_VBLANK,D0
  171.         moveq.l     #0,D1
  172.         libcall     OpenDevice        ; (A0=devname,D0=unit,A1=ioRequest,d1=flags)
  173.  
  174.         tst.l        D0
  175.         bne        NoTimerDevice    ; OpenDevice failed
  176.  
  177. ;    Start a timer. CheckIO will crash if no timer is started
  178.         moveq.l     #1,D0         ; Shortest possible timer 1/50s
  179.         call        QueTimer         ; (D0=length)
  180.  
  181. ; ---------------------------------------------------------------------------------
  182.  
  183. ;    Create a semaphore to use in the intuition patch
  184. ;      the semaphore is in this code segment so we can reach
  185. ;      it directly in the patched functions.
  186.         lea        PopUpSemaphore(PC),A0
  187.         libcall     InitSemaphore    ; (A0=sigSem)
  188.  
  189. ;    Patch the Intuition function to use the semaphore
  190. ;    ClearMenuStrip, OnMenu, OffMenu, must be patched.
  191. ;     SetMenuStrip and ResetMenuStrip not needed since Programs are not
  192. ;     allowed to use these functions without clearing the menu-strip
  193. ;     with ClearMenuStrip before.
  194. ;
  195. ;    Patch    ClearMenuStrip
  196.  
  197.         lea        @MyClearMenuStrip(PC),A0
  198.         move.l        A0,D0
  199.         move.l        _IntuitionBase(A4),A1
  200.         move.w        #_LVOClearMenuStrip,A0
  201.         libcall     SetFunction     ; (A1=library,A0=funcOffset,D0=newFunction)
  202.  
  203.         move.l        D0,OldClearMenuStrip
  204.         beq        NoClearMenuPatch
  205.  
  206. ;    Patch    OnMenu
  207.         lea        @MyOnMenu(PC),A0
  208.         move.l        A0,D0
  209.         move.l        _IntuitionBase(A4),A1
  210.         move.w        #_LVOOnMenu,A0
  211.         libcall     SetFunction     ; (A1=library,A0=funcOffset,D0=newFunction)
  212.  
  213.         move.l        D0,OldOnMenu
  214.         beq        NoOnMenuPatch
  215.  
  216. ;    Patch    OffMenu
  217.         lea        @MyOffMenu(PC),A0
  218.         move.l        A0,D0
  219.         move.l        _IntuitionBase(A4),A1
  220.         move.w        #_LVOOffMenu,A0
  221.         libcall     SetFunction     ; (A1=library,A0=funcOffset,D0=newFunction)
  222.  
  223.         move.l        D0,OldOffMenu
  224.         beq        NoOffMenuPatch
  225.  
  226. ; ---------------------------------------------------------------------------
  227. ;    Init the datafield for the inputhandler
  228.         lea        _CxHandlerData(A4),A2
  229.  
  230. ;    Poiter to our task
  231.         move.l        A5,ssd_PopUpMenuTask(A2)
  232.  
  233. ;    Clear other fields (Flags, EndQualifier)
  234. ;[Not needed]    moveq.l     #0,D0
  235. ;        move.b        D0,ssd_Flags(A2)
  236. ;        move.w        D0,ssd_EndQualifier(A2)
  237.  
  238. ;    We need a lot of signals, make a loop
  239.         lea        ssd_FirstSignal(A2),A3
  240.         moveq.l     #NO_OF_SIGNALS-1,D2
  241.  
  242. NextSignal    moveq.l     #-1,D0
  243.         libcall     AllocSignal     ; (D0=signalNum)
  244.  
  245.         move.w        D0,ssi_Num(A3)
  246.         bmi        NoSignal
  247.  
  248.         moveq.l     #1,D1
  249.         asl.l        D0,D1
  250.         move.l        D1,ssi_Mask(A3)
  251.  
  252.         addq.l        #ssi_SIZEOF,A3
  253.         dbra        D2,NextSignal
  254.  
  255. ; ----------------------------------------------------------------------------
  256. ;    Add a notify on the IControlPrefs
  257.  
  258.         lea        NotifyData(PC),A3
  259.         move.b        ssd_NotifySig+ssi_Num+1(A2),nr_SignalNum(A3)
  260.         move.l        A5,nr_Task(A3)      ; A5 = ThisTask
  261.  
  262.         move.l        _DOSBase(A4),A6
  263.         move.l        A3,D1
  264.         libcall     StartNotify     ; (D1=notify)
  265.  
  266.         tst.l        D0
  267.         bpl        NoFileNotify
  268.  
  269. ; ----------------------------------------------------------------------------
  270. ;                 Broker
  271. ;                /      \
  272. ;               Custom      Filter (Hotkey)
  273. ;                  /    \
  274. ;                  Signal    Translate
  275. ;
  276.         move.l        _CxBase(A4),A6
  277.  
  278. ;    Create a custom object
  279.         moveq.l     #CX_CUSTOM,D0
  280.         lea        @PopUpHandler(PC),A0
  281.         move.l        A2,A1        ; A2 = _CxHandlerData
  282.         libcall     CreateCxObj     ; (D0=type,A0=arg1,A1=arg2)
  283.  
  284.         move.l        D0,A1
  285.         move.l        A1,D0
  286.         beq        NoCustomCxObj
  287.  
  288. ;    Attach it to the broker
  289.         move.l        _PopUpBroker(A4),A0
  290.         libcall     AttachCxObj     ; (A0 = headObj,A1=co)
  291.  
  292. ; ---------------------------------------------------------------------------
  293.  
  294. ;    Add the hotkey to broker
  295. ;    Create a filter object
  296.         moveq.l     #CX_FILTER,D0
  297.         lea        _HotKeyString(A4),A0
  298.         sub.l        A1,A1
  299.         libcall     CreateCxObj     ; (D0=type,A0=arg1,A1=arg2)
  300.  
  301.         move.l        D0,_HotKeyFilterCxObj(A4)
  302.         beq        NoFilterCxObj
  303.         move.l        D0,A2       ; Save filter object in A2
  304.  
  305. ;    Check errorcode
  306.         move.l        A2,A0
  307.         libcall     CxObjError        ; (A0=co)
  308.  
  309.         tst.l        D0
  310.         beq        FilterOK
  311.  
  312. ;    the Hotkey was bad => change to default
  313.         lea        DEFAULTHOTKEY(PC),A0
  314.         lea        _HotKeyString(A4),A1
  315. 1$        move.b        (A0)+,(A1)+
  316.         bne        1$
  317.  
  318.         move.l        A2,A0
  319.         lea        DEFAULTHOTKEY(PC),A1
  320.         libcall     SetFilter        ; (A0=filter,A1=text)
  321.  
  322.         bset        #OPENOPTWINDOW_B0,_CxHandlerData+ssd_Options(A4)
  323.  
  324. ;    Attach filter to the broker
  325. FilterOK:    move.l        A2,A1
  326.         move.l        _PopUpBroker(A4),A0
  327.         libcall     AttachCxObj     ; (A0=headObj,A1=co)
  328.  
  329. ;    Create a signal object    (CTRL F means wake up)
  330.         moveq.l     #CX_SIGNAL,D0
  331.         move.l        A5,A0      ; A5 = ThisTask
  332.         sub.l        A1,A1
  333.         move.w        #SIGBREAKB_CTRL_F,A1
  334.         libcall     CreateCxObj     ; (D0=type,A0=arg1,A1=arg2)
  335.  
  336.         move.l        D0,A1
  337.         move.l        A1,D0
  338.         beq        NoSignalCxObj
  339.  
  340. ;    Attach it to the filter
  341.         move.l        A2,A0    ; Filter object
  342.         libcall     AttachCxObj     ; (A0=headObj,A1=co)
  343.  
  344. ;    Create a translator object to remove the hotkey event
  345.         moveq.l     #CX_TRANSLATE,D0
  346.         sub.l        A0,A0
  347.         sub.l        A1,A1
  348.         libcall     CreateCxObj     ; (D0=type,A0=arg1,A1=arg2)
  349.  
  350.         move.l        D0,A1
  351.         move.l        A1,D0
  352.         beq        NoTranslatorCxObj
  353.  
  354. ;    Attach it to the filter object
  355.         move.l        A2,A0
  356.         libcall     AttachCxObj     ; (A0=headObj,A1=co)
  357.  
  358. ; ------------------------------------------------------------------------------
  359. ;    Activate the broker
  360.         move.l        _PopUpBroker(A4),A0
  361.         moveq.l     #TRUE,D0
  362.         libcall     ActivateCxObj    ; (A0=co,D0=true)
  363.  
  364. ;    Everything opened OK start the main loop
  365.  
  366.         call        PopUpMainLoop
  367.  
  368.         move.l        _PopUpBroker(A4),A0
  369.         moveq.l     #FALSE,D0
  370.         libcall     ActivateCxObj    ; (A0=co,D0=true)
  371.  
  372. ;    All CXObj:s are removed together with the broker
  373. NoTranslatorCxObj:
  374. NoSignalCxObj:
  375. NoFilterCxObj:
  376. NoCustomCxObj:    move.l        _DOSBase(A4),A6
  377.         lea        NotifyData(PC),A0
  378.         move.l        A0,D1
  379.         libcall     EndNotify        ; (D1=notify)
  380.  
  381. NoFileNotify:    move.l        _ExecBase(A4),A6
  382.         lea        _CxHandlerData+ssd_LastSignal(A4),A3
  383.         moveq.l     #-1,D2
  384.  
  385. NoSignal1:    moveq.l     #0,D0
  386.         move.w        ssi_Num(A3),D0
  387.         libcall     FreeSignal        ; (D0=signalNum)
  388.  
  389.         addq.w        #1,D2
  390.  
  391. NoSignal:    subq.l        #ssi_SIZEOF,A3
  392.         cmp.w        #NO_OF_SIGNALS-1,D2
  393.         bne        NoSignal1
  394.  
  395. NoSignal2:    move.l        OldOffMenu(PC),D0
  396.         move.l        _IntuitionBase(A4),A1
  397.         move.w        #_LVOOffMenu,A0
  398.         libcall     SetFunction     ; (A1=library,A0=funcOffset,D0=newFunction)
  399.  
  400. NoOffMenuPatch: move.l        OldOnMenu(PC),D0
  401.         move.l        _IntuitionBase(A4),A1
  402.         move.w        #_LVOOnMenu,A0
  403.         libcall     SetFunction     ; (A1=library,A0=funcOffset,D0=newFunction)
  404.  
  405. NoOnMenuPatch:    move.l        OldClearMenuStrip(PC),D0
  406.         move.l        _IntuitionBase(A4),A1
  407.         move.w        #_LVOClearMenuStrip,A0
  408.         libcall     SetFunction     ; (A1=library,A0=funcOffset,D0=newFunction)
  409.  
  410. NoClearMenuPatch:
  411.         move.l        _TimerReqBlock(A4),A1
  412.         libcall     CloseDevice     ; (A1=ioRequest)
  413.  
  414. NoTimerDevice:    move.l        _TimerReqBlock(A4),A0
  415.         libcall     DeleteIORequest    ; (A0=ioRequest)
  416.  
  417. NoTimerIOStdReq:
  418.         move.l        _TimerPort(A4),A0
  419.         libcall     DeleteMsgPort    ; (A0=port)
  420.  
  421. NoTimerPort:    move.l        _ReplyPort(A4),A0
  422.         libcall     DeleteMsgPort    ; (A0=port)
  423.  
  424. NoReplyPort:    move.l        _LayersBase(A4),A1
  425.         libcall     CloseLibrary    ; (A1=library)
  426.  
  427. NoLayers:    move.l        _GfxBase(A4),A1
  428.         libcall     CloseLibrary    ; (A1=library)
  429.  
  430. NoGraphics:    move.l        _IntuitionBase(A4),A1
  431.         libcall     CloseLibrary    ; (A1=library)
  432.  
  433. NoIntuition:    move.l        _CxBase(A4),A6
  434.         move.l        _PopUpBroker(A4),A0
  435.         libcall     DeleteCxObjAll    ; (A0=co)
  436.  
  437. NoBroker:    move.l        _ExecBase(A4),A6
  438.         move.l        _CxBase(A4),A1
  439.         libcall     CloseLibrary    ; (A1=library)
  440.  
  441.         lea        BrokerData(PC),A2
  442.  
  443. NoCommodity:    move.l        nb_Port(A2),A0
  444.         call        MyDeletePort    ; (A0=port)
  445.  
  446. NoBrokerPort:    move.l        _DOSBase(A4),A1
  447.         libcall     CloseLibrary    ; (A1=library)
  448.  
  449. NoDos:        move.l        _WBenchMsg(A4),D3
  450.         beq        NoDos1
  451.  
  452.         libcall     Forbid        ; ()
  453.  
  454.         move.l        D3,A1
  455.         libcall     ReplyMsg        ; (A1=message)
  456.  
  457. NoDos1:     lea        Globals_SIZEOF(SP),SP
  458.         moveq.l     #0,D0
  459.         rts
  460.  
  461. ;*************************
  462. ;*  VOID PopUpMainLoop() *
  463. ;*************************
  464. QUIT_B        equ        0
  465. VERIFYOK_B    equ        1
  466. POPUP_B     equ        2
  467. ACTIVEWAITING_B equ        3
  468. DISAPPEAR_B    equ        4
  469. APPEAR_B    equ        5
  470. ENABLE_B    equ        6
  471. DISABLE_B    equ        7
  472.  
  473. QUIT_F        equ        %00000001
  474. VERIFYOK_F    equ        %00000010
  475. POPUP_F     equ        %00000100
  476. ACTIVEWAITING_F equ        %00001000
  477. DISAPPEAR_F    equ        %00010000
  478. APPEAR_F    equ        %00100000
  479. ENABLE_F    equ        %01000000
  480. DISABLE_F    equ        %10000000
  481.  
  482. VERIFYMSG    equ        TRUE
  483. MENUUPMSG    equ        FALSE
  484.  
  485.         STRUCTURE   MainLocal,0
  486.         UWORD        loc_TimeOut
  487.         ULONG        loc_Signals
  488.         ULONG        loc_BrokerSigMask
  489.         ULONG        loc_ReplySigMask
  490.         LABEL        loc_SIZEOF
  491.  
  492. ;* D2 = SignalBits
  493. ;* D3 = Magic
  494. ;* D4 = TotalMessages
  495. ;* D5 = OptWinSig
  496. ;* D6 = Flags
  497. ;* D7 = NrOfMessages
  498.  
  499. @PopUpMainLoop: movem.l     D2-D7/A2-A3/A6,-(SP)
  500.         lea        -loc_SIZEOF(SP),SP
  501.  
  502. ;  NrOfMessages = OptWinSig = TotalMessages = Magic = 0
  503.         moveq.l     #0,D7
  504.         move.l        D7,D5
  505.         move.l        D7,D4
  506.         move.l        D7,D3
  507.  
  508. ;  Flags = Options & OPENOPTWINDOW  [OPENOPTWINDOW == APPEAR_FLAG]
  509.         move.b        _CxHandlerData+ssd_Options(A4),D6
  510.         and.b        #OPENOPTWINDOW,D6
  511.  
  512. ;  ReplySigMask = 1 << ReplyPort->mp_SigBit
  513.         moveq.l     #0,D0
  514.         move.l        _ReplyPort(A4),A0
  515.         moveq.l     #1,D2
  516.         move.b        MP_SIGBIT(A0),D0
  517.         asl.l        D0,D2
  518.         move.l        D2,loc_ReplySigMask(SP)
  519.  
  520. ;  BrokerSigMask = 1 << BrokerData.nb_Port->mp_SigBit
  521.         lea        BrokerData+nb_Port(PC),A0
  522.         move.l        (A0),A0
  523.         move.b        MP_SIGBIT(A0),D0
  524.         moveq.l     #1,D1
  525.         asl.l        D0,D1
  526.         move.l        D1,loc_BrokerSigMask(SP)
  527.         or.l        D1,D2
  528.  
  529. ;  TimerSigMask = 1 << TimerPort->mp_SigBit
  530.         move.l        _TimerPort(A4),A0
  531.         move.b        MP_SIGBIT(A0),D0
  532.         moveq.l     #1,D1
  533.         asl.l        D0,D1
  534.         move.l        D1,_TimerSigMask(A4)
  535.         or.l        D1,D2
  536.  
  537. ;  Signals = ReplySigMask | BrokerSigMask | TimerSigMask |
  538. ;         MenuUpSigMask | MenuDownSigMask | NotifySigMask |
  539. ;         SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_F
  540.         or.l        _CxHandlerData+ssd_MenuUpSig+ssi_Mask(A4),D2
  541.         or.l        _CxHandlerData+ssd_MenuDownSig+ssi_Mask(A4),D2
  542.         or.l        _CxHandlerData+ssd_NotifySig+ssi_Mask(A4),D2
  543.         or.w        #SIGBREAKF_CTRL_C!SIGBREAKF_CTRL_F,D2
  544.         move.l        D2,loc_Signals(SP)
  545.  
  546. ;  TimeOut = GetTimeOutPrefs()
  547.         call        GetTimeOutPrefs
  548.  
  549.         move.w        D0,(SP)     ; loc_TimeOut
  550.  
  551. ;  SignalBits = Wait(Signals | OptWinSig)
  552. WaitEvent:    move.l        _ExecBase(A4),A6
  553.         move.l        loc_Signals(SP),D0
  554.         or.l        D5,D0
  555.         libcall     Wait    ; (d0=signalSet)
  556.  
  557.         move.l        D0,D2
  558.  
  559. ;   SignalBits & MenuUpSigMask ?
  560. MenuUpEvent:    and.l        _CxHandlerData+ssd_MenuUpSig+ssi_Mask(A4),D0
  561.         beq        MenuDownEvent
  562.  
  563. ;  Flags & POPUP_FLAG ?   [No preparation is done]
  564.         btst        #POPUP_B,D6
  565.         beq        ReplyEvent
  566.  
  567. ;  NrOfMessages = 0  [forget messages sent]
  568.         moveq.l     #0,D7
  569.  
  570. ;  Magic += 1         [stop counting them]
  571.         addq.l        #1,D3
  572.  
  573. ;  TotalMessages += SendMessage(MENUUPMSG,0)  [Send cancel messages]
  574.         moveq.l     #0,D0
  575.         moveq.l     #0,D1
  576.         call        SendMessages
  577.  
  578.         add.w        D0,D4
  579.  
  580. ;  Flags &= (QUIT_FLAG | DISABLE_FLAG)       Clear all Flags
  581.         and.b        #QUIT_F!DISABLE_F,D6
  582.  
  583. ;  AbortTimer()   Prepare for a new MENU_DOWN
  584.         call        AbortTimer
  585.  
  586.         bra        ReplyEvent
  587.  
  588. ;  SignalBits & MenuDownSigMask ?
  589. MenuDownEvent:    move.l        D2,D0
  590.         and.l        _CxHandlerData+ssd_MenuDownSig+ssi_Mask(A4),D0
  591.         beq        ReplyEvent
  592.  
  593. ;  Lock = LockIBase(0)
  594.         move.l        _IntuitionBase(A4),A6
  595.         moveq.l     #0,D0
  596.         libcall     LockIBase        ; (d0=dontknow)
  597.  
  598.         move.l        D0,A2
  599.  
  600. ;  ActiveWindow = IntuitionBase->ActiveWindow
  601.         move.l        ib_ActiveWindow(A6),A3
  602.         move.l        A3,_ActiveWindow(A4)
  603.  
  604.         move.l        A3,D0
  605.         beq        2$
  606.  
  607. ;  Screen = ActiveWindow->WScreen
  608.         move.l        wd_WScreen(A3),_Screen(A4)
  609.  
  610. ;  Send messages to every window with MENUVERIFY set
  611. ;  TotalMessages += NrOfMessages = SendMessage(VERIFYMSG,Magic)
  612.         moveq.l     #VERIFYMSG,D0
  613.         move.l        D3,D1
  614.         call        SendMessages
  615.  
  616.         add.w        D0,D4
  617.         move.l        D0,D7
  618.  
  619. ;  NrOfMessages > 0 ?      if messages were sent start a timer
  620.         beq        1$
  621.  
  622. ;  QueTimer(TimeOut)
  623.         move.w        (SP),D0      ; loc_TimeOut
  624.         call        QueTimer
  625.  
  626. ;  ActiveWindow->IDCMPFlags & IDCMP_MENUVERIFY
  627.         btst        #IDCMP_MENUVERIFY_B2,wd_IDCMPFlags+2(A3)
  628.         beq        1$
  629.  
  630. ;  Flags |= ACTIVEWAITING_FLAG
  631.         bset        #ACTIVEWAITING_B,D6
  632.  
  633. ;  Flags |= POPUP_FLAG | VERIFYOK_FLAG         Pop-up the menus ASAP
  634. 1$        or.b        #POPUP_F!VERIFYOK_F,D6
  635.  
  636. ;  UnlockIBase(Lock)
  637. 2$        move.l        A2,A0
  638.         libcall     UnlockIBase     ; (a0=iblock)
  639.  
  640.         move.l        _ExecBase(A4),A6
  641. ;  /*-----------------------------------------------------------------------------*/
  642. ;  SignalBits & ReplySigMask
  643. ReplyEvent:    move.l        D2,D0
  644.         and.l        loc_ReplySigMask(SP),D0
  645.         beq        TimerEvent
  646.  
  647. ;  Message = GetMsg(ReplyPort)
  648. MoreReplies    move.l        _ReplyPort(A4),A0
  649.         libcall     GetMsg    ; (A0=port)
  650.  
  651.         move.l        D0,A1
  652.         move.l        A1,D0
  653.         beq        TimerEvent
  654.  
  655. ;  MENUVERIFY message ?
  656.         btst        #IDCMP_MENUVERIFY_B2,im_Class+2(A1)
  657.         beq        2$
  658.  
  659. ;  Message->mmn_Session == Magic  ?   [ is it an old message ]
  660.         cmp.l        mmn_Session(A1),D3
  661.         bne        2$
  662.  
  663. ;  The active window may cancel the menu operation
  664. ;  Message->IDCMPWindow == ActiveWindow ?
  665.         move.l        im_IDCMPWindow(A1),A0
  666.         cmp.l        _ActiveWindow(A4),A0
  667.         bne        1$
  668.  
  669. ;  Flags &= ~ACTIVEWAITING_FLAG  [active window has replied]
  670.         bclr        #ACTIVEWAITING_B,D6
  671.  
  672. ;  Message->Code == MENUCANCEL
  673.         cmp.w        #MENUCANCEL,im_Code(A1)
  674.         bne        1$
  675.  
  676. ;  Flags &= ~VERIFYOK_FLAG  [ do not pop-up the menus ]
  677.         bclr        #VERIFYOK_B,D6
  678.  
  679. ;  NrOfMessages -= 1
  680. 1$        subq.w        #1,D7
  681.  
  682. ;  if it was not MENUVERIFY then it must be MOUSEBUTTONS message
  683. ;  FreeMem(Message,sizeof(struct MyMsg))
  684. 2$        moveq.l     #mmn_SIZEOF,D0
  685.         libcall     FreeMem    ; (A1=memoryBlock,D0=byteSize)
  686.  
  687. ;  TotalMessages -= 1
  688.         subq.w        #1,D4
  689.  
  690.         bra        MoreReplies
  691.  
  692. ;  /*-----------------------------------------------------------------------------*/
  693. ;  SignalBits & TimerSigMask ?
  694. TimerEvent:    move.l        D2,D0
  695.         and.l        _TimerSigMask(A4),D0
  696.         beq        AllReplied
  697.  
  698. ;  GetMsg(TimerPort)  Get rid of the message
  699.         move.l        _TimerPort(A4),A0
  700.         libcall     GetMsg        ; (A0=port)
  701.  
  702.         tst.l        D0
  703.         beq        AllReplied
  704.  
  705. ;  did the active window reply before timeout ?
  706. ;  Flags & ACTIVEWAITING_FLAG ?
  707.         btst        #ACTIVEWAITING_B,D6
  708.         beq        1$
  709.  
  710. ;  Flags &= ~VERIFYOK_FLAG  [ cancel menu operation ]
  711.         bclr        #VERIFYOK_B,D6
  712.  
  713. ;  NrOfMessages = 0      forget messages sent
  714. 1$        moveq.l     #0,D7
  715.  
  716. ;  Magic += 1           don't count them
  717.         addq.l        #1,D3
  718.  
  719. ;  /*-----------------------------------------------------------------------------*/
  720. ;  ready to pop-up the menus ?
  721. ;  NrOfMessages == 0 AND Flags & (POPUP_FLAG | VERIFYOK_FLAG) == (POPUP_FLAG | VERIFYOK_FLAG)) {
  722. AllReplied:    tst.w        D7
  723.         bne        BrokerMessage
  724.         move.b        D6,D0
  725.         and.b        #POPUP_F!VERIFYOK_F,D0
  726.         subq.b        #POPUP_F!VERIFYOK_F,D0
  727.         bne        BrokerMessage
  728.  
  729. ;  PopUpMenu()
  730.         call        PopUpMenu
  731.  
  732.         bclr        #VERIFYOK_B,D6
  733.         tst.w        D0            ; MENUUP Handled ?
  734.         beq        BrokerMessage   ; No
  735.  
  736. ;  TotalMessages += SendMessage(MENUUPMSG,0) [PopUpMenu ended with MENUUP]
  737.         moveq.l     #MENUUPMSG,D0
  738.         moveq.l     #0,D1
  739.         call        SendMessages
  740.  
  741.         add.w        D0,D4
  742.  
  743. ;  Flags &= (QUIT_FLAG | DISABLE_FLAG)
  744.         and.b        #QUIT_F!DISABLE_F,D6
  745.  
  746. ;  /*-----------------------------------------------------------------------------*/
  747. ;  SignalBits & BrokerSigMask ?
  748. BrokerMessage:    move.l        D2,D0
  749.         and.l        loc_BrokerSigMask(SP),D0
  750.         beq        CTRLCEvent
  751.  
  752. ;  Message = GetMsg(BrokerData.nb_Port)
  753. MoreBrokerMsg:    lea        BrokerData+nb_Port(PC),A0
  754.         move.l        (A0),A0
  755.         libcall     GetMsg    ; (A0=port)
  756.  
  757.         move.l        D0,A2
  758.         move.l        A2,D0
  759.         beq        CTRLCEvent
  760.  
  761. ;  CxMsgType(Message) == CXM_COMMAND [ should be the only possible message ]
  762.         move.l        _CxBase(A4),A6
  763.         move.l        A2,A0
  764.         libcall     CxMsgType
  765.  
  766.         moveq.l     #CXM_COMMAND,D1
  767.         cmp.l        D0,D1
  768.         bne        ReplyBroker
  769.  
  770. ;  Set flags according to command sent
  771.         move.l        A2,A0
  772.         libcall     CxMsgID
  773.  
  774.         lea        CXCMDCOMMANDS(PC),A0
  775.         moveq.l     #NoOfCommands-1,D1
  776. 1$        cmp.b        (A0),D0
  777.         bne        2$
  778.         or.b        1(A0),D6
  779.         bra        ReplyBroker
  780.  
  781. 2$        addq.l        #2,A0
  782.         dbra        D1,1$
  783.  
  784. ;  ReplyMsg(Message);
  785. ReplyBroker:    move.l        _ExecBase(A4),A6
  786.         move.l        A2,A1
  787.         libcall     ReplyMsg    ; (A1=message)
  788.  
  789.         bra        MoreBrokerMsg
  790.  
  791. ;  /*-----------------------------------------------------------------------------*/
  792. ;  SignalBits & SIGBREAKF_CTRL_C ?
  793. CTRLCEvent:    btst        #SIGBREAKB_CTRL_C,D2
  794.         beq        OptWinEvent
  795.  
  796. ;  Flags |= (QUIT_FLAG | DISAPPEAR_FLAG | DISABLE_FLAG)
  797.         or.b        #QUIT_F!DISAPPEAR_F!DISABLE_F,D6
  798.  
  799. ;  /*-----------------------------------------------------------------------------*/
  800. ;  SignalBits & OptWinSig ?
  801. OptWinEvent:    move.l        D2,D0
  802.         and.l        D5,D0
  803.         beq        CTRLFEvent
  804.  
  805. ;  HandleOptWindow()
  806.         call        HandleOptWindow
  807.  
  808.         tst.w        D0
  809.  
  810. ;  No change
  811.         beq        CTRLFEvent
  812.         bpl        1$
  813.  
  814. ;  User wants to quit
  815. ;  Flags |= (QUIT_FLAG | DISAPPEAR_FLAG | DISABLE_FLAG)
  816.         or.b        #QUIT_F!DISABLE_F,D6
  817.  
  818. ;  User wants to close the window
  819. ;  Flags |= DISAPPEAR_FLAG
  820. 1$        bset        #DISAPPEAR_B,D6
  821.  
  822. ;  /*---------------------------------------------------------------------------*/
  823. ;  SignalBits & SIGBREAKF_CTRL_F
  824. CTRLFEvent:    btst        #SIGBREAKB_CTRL_F,D2
  825.         beq        NotifyEvent
  826.  
  827. ;  Flags |= (APPEAR_FLAG | ENABLE_FLAG)
  828.         or.b        #APPEAR_F!ENABLE_F,D6
  829.  
  830. ;  /*-----------------------------------------------------------------------------*/
  831. ;  SignalBits & NotifySigMask
  832. NotifyEvent:    move.l        D2,D0
  833.         and.l        _CxHandlerData+ssd_NotifySig+ssi_Mask(A4),D0
  834.         beq        CheckFlags
  835.  
  836. ;  TimeOut = GetTimeOutPrefs()
  837.         call        GetTimeOutPrefs
  838.  
  839.         move.w        D0,(SP)     loc_TimeOut
  840.  
  841. ;  /*-----------------------------------------------------------------------------*/
  842. ;  if (Flags & DISAPPEAR_FLAG)
  843. CheckFlags:    btst        #DISAPPEAR_B,D6
  844.         beq        1$
  845.  
  846. ;  window open ?
  847.         tst.l        D5
  848.         beq        1$
  849.  
  850. ;  CloseOptWindow()
  851.         call        CloseOptWindow
  852.  
  853. ;  OptWinSig = 0
  854.         moveq.l     #0,D5
  855.  
  856. ;  Handle the different flags
  857. ;  Flags & APPEAR_FLAG     [ Open window or bring it to front ]
  858. 1$        btst        #APPEAR_B,D6
  859.         beq        2$
  860.  
  861. ;  OptWinSig = OpenOptWindow(OptWinSig)
  862.         move.l        D5,D0
  863.         call        OpenOptWindow
  864.  
  865.         move.l        D0,D5
  866.  
  867. ;  Flags & ENABLE_FLAG    [ Enable the broker ]
  868. 2$        btst        #ENABLE_B,D6
  869.         beq        3$
  870.  
  871. ;  ActivateCxObj(PopUpBroker,TRUE)
  872.         move.l        _CxBase(A4),A6
  873.         move.l        _PopUpBroker(A4),A0
  874.         moveq.l     #TRUE,D0
  875.         libcall     ActivateCxObj
  876.  
  877. ;  Flags &= ~QUIT_FLAG;
  878.         bclr        #QUIT_F,D6
  879.  
  880. ;  Flags & DISABLE_FLAG   [ disable the broker ]
  881. 3$        btst        #DISABLE_B,D6
  882.         beq        4$
  883.  
  884. ;  Flags & POPUP_FLAG == 0   [ can't disable if we are waiting to popup ]
  885.         btst        #POPUP_B,D6
  886.         bne        4$
  887.  
  888. ;  ActivateCxObj((struct CxObj *)PopUpBroker,FALSE)
  889.         move.l        _CxBase(A4),A6
  890.         move.l        _PopUpBroker(A4),A0
  891.         moveq.l     #FALSE,D0
  892.         libcall     ActivateCxObj
  893.  
  894. ;  Flags &= ~DISABLE_FLAG
  895.         bclr        #DISABLE_B,D6
  896.  
  897. ;  We can't quit if some windows have not replied yet
  898. ;  TotalMessages == 0 AND Flags & QUIT_FLAG AND Flags & DISABLE_FLAG == 0
  899. 4$        tst.w        D4
  900.         bne        5$
  901.         btst        #QUIT_B,D6
  902.         beq        5$
  903.         btst        #DISABLE_B,D6
  904.         beq        MainLoopDone
  905.  
  906. ;  These flags do not survive multiple events
  907. ;  Flags &= ~(DISAPPEAR_FLAG | APPEAR_FLAG | ENABLE_FLAG)
  908. 5$        and.b        #~(DISAPPEAR_F!APPEAR_F|ENABLE_F),D6
  909.         bra        WaitEvent
  910.  
  911. MainLoopDone:    lea        loc_SIZEOF(SP),SP
  912.         movem.l     (SP)+,D2-D7/A2-A3/A6
  913.         rts
  914.  
  915. ;****************************************************
  916. ;* UWORD SendMessages(UWORD Kind, ULONG MagicCode)  *
  917. ;*                            *
  918. ;* Input:                        *
  919. ;*   Kind    MENUVERIFY or MOUSEBUTTONS messages *
  920. ;*   MagicCode    Session number                *
  921. ;* Output:                        *
  922. ;*   return    Messages sent                *
  923. ;****************************************************
  924. @SendMessages:    movem.l     D2-D4/A2-A3/A6,-(SP)
  925.         move.l        D0,D2
  926.         move.l        D1,D3
  927.  
  928. ;  Forbid while we are moving through the list.
  929. ;  don't know if LockIBase supports multiple locks from same task.
  930.         move.l        _ExecBase(A4),A6
  931.         libcall     Forbid    ; ()
  932.  
  933. ;  NrOfMessages = 0
  934.         moveq.l     #0,D4
  935.  
  936. ;  Window = Screen->FirstWindow
  937.         move.l        _Screen(A4),A0
  938.         move.l        sc_FirstWindow(A0),A3
  939.         bra        CheckWindow
  940.  
  941. ;  Window->IDCMPFlags & IDCMP_MENUVERIFY
  942. NextWindow:    btst        #IDCMP_MENUVERIFY_B2,wd_IDCMPFlags+2(A3)
  943.         beq        NoMenuVerify
  944.  
  945. ;  Message = AllocMem(sizeof(struct MyMsg),MEMF_PUBLIC|MEMF_CLEAR)
  946.         moveq.l     #mmn_SIZEOF,D0
  947.         move.l        #MEMF_PUBLIC!MEMF_CLEAR,D1
  948.         libcall     AllocMem
  949.  
  950.         move.l        D0,A2
  951.         tst.l        D0
  952.         beq        NoMemory
  953.  
  954. ;  Message->mmn_IntuiMessage.ExecMessage.mn_Node.ln_Type = NT_MESSAGE
  955.         move.b        #NT_MESSAGE,im_ExecMessage+LN_TYPE(A2)
  956.  
  957. ;  Message->mmn_IntuiMessage.ExecMessage.mn_ReplyPort = ReplyPort
  958.         move.l        _ReplyPort(A4),im_ExecMessage+MN_REPLYPORT(A2)
  959.  
  960. ;  Message->mmn_IntuiMessage.ExecMessage.mn_Length = sizeof(struct IntuiMessage)
  961.         move.w        #im_SIZEOF,im_ExecMessage+MN_LENGTH(A2)
  962.  
  963. ;  Kind == VERIFYMSG
  964.         tst.w        D2
  965.         beq        1$
  966.  
  967. ;  Message->mmn_IntuiMessage.Class = IDCMP_MENUVERIFY
  968.         moveq.l     #0,D0
  969.         bset        #IDCMP_MENUVERIFY_B2+8,D0
  970.  
  971. ;  the active window should have a MENUHOT code all others MENUWAITING
  972.         moveq.l     #MENUWAITING,D1
  973.         cmp.l        _ActiveWindow(A4),A3
  974.         bne        2$
  975.  
  976.         moveq.l     #MENUHOT,D1
  977.         bra        2$
  978.  
  979. ;  Message->mmn_IntuiMessage.Class = IDCMP_MOUSEBUTTONS
  980. 1$        moveq.l     #IDCMP_MOUSEBUTTONS,D0
  981.  
  982. ;  Message->mmn_IntuiMessage.Code = MENUUP
  983.         move.w        #MENUUP,D1          ; MENUUP
  984.  
  985. 2$        move.l        D0,im_Class(A2)
  986.         move.w        D1,im_Code(A2)
  987.  
  988. ;  Message->mmn_IntuiMessage.Qualifier = CxHandlerData.ssd_EndQualifier
  989.         move.w        _CxHandlerData+ssd_EndQualifier(A4),im_Qualifier(A2)
  990.  
  991. ;  Message->mmn_IntuiMessage.IDCMPWindow = Window
  992.         move.l        A3,im_IDCMPWindow(A2)
  993.  
  994. ;  CurrentTime(&Message->mmn_IntuiMessage.Seconds, &Message->mmn_IntuiMessage.Micros)
  995.         lea        im_Seconds(A2),A0
  996.         lea        im_Micros(A2),A1
  997.         move.l        _IntuitionBase(A4),A6
  998.         libcall     CurrentTime
  999.  
  1000. ;  Dont set mouse position if window has DELTAMOVE
  1001.         btst        #IDCMP_DELTAMOVE_B1,wd_IDCMPFlags+1(A3)
  1002.         bne        3$
  1003.  
  1004. ;  Message->mmn_IntuiMessage.MouseX = Window->MouseX
  1005. ;  Message->mmn_IntuiMessage.MouseY = Window->MouseY
  1006.         move.w        wd_MouseX(A3),im_MouseX(A2)
  1007.         move.w        wd_MouseY(A3),im_MouseY(A2)
  1008.  
  1009. ;  Message->mmn_Session = MagicCode
  1010. 3$        move.l        D3,mmn_Session(A2)
  1011.  
  1012. ;  PutMsg(Window->UserPort, Message)
  1013.         move.l        _ExecBase(A4),A6
  1014.         move.l        wd_UserPort(A3),A0
  1015.         move.l        A2,A1
  1016.         libcall     PutMsg
  1017.  
  1018. ;  NrOfMessages += 1
  1019.         addq.w        #1,D4
  1020.  
  1021. ;  Window = Window->NextWindow
  1022. NoMemory:
  1023. NoMenuVerify:    move.l        wd_NextWindow(A3),A3
  1024.  
  1025. CheckWindow:    move.l        A3,D0
  1026.         bne        NextWindow
  1027.  
  1028. NoMoreWindows:    libcall     Permit    ; ()
  1029.  
  1030.         move.l        D4,D0
  1031.         movem.l     (SP)+,D2-D4/A2-A3/A6
  1032.         rts
  1033.  
  1034. ;***********************************************************
  1035. ;* GetTimeOutPrefs()  - read timeout value from prefs file *
  1036. ;***********************************************************
  1037. ; We do only need to read up to the TimeOut field
  1038. TimeOutBytes    equ        ic_TimeOut+2
  1039.  
  1040. @GetTimeOutPrefs:
  1041.         movem.l     D2/D3/A2/A3/A6,-(SP)
  1042.  
  1043. ;   TimeOut = DEFAULT_TIMEOUT
  1044.         moveq.l     #DEFAULT_TIMEOUT,D3
  1045.  
  1046. ;   IFFParseBase = OpenLibrary("iffparse.library",KICK204)
  1047.         move.l        _ExecBase(A4),A6
  1048.         lea        IFFNAME(PC),A1
  1049.         moveq.l     #KICK204,D0
  1050.         libcall     OpenLibrary
  1051.  
  1052.         tst.l        D0
  1053.         beq        NoIFFLib
  1054.  
  1055.         move.l        D0,A2
  1056.  
  1057. ;   IFFHandle = AllocIFF()
  1058.         move.l        A2,A6
  1059.         libcall     AllocIFF
  1060.  
  1061.         tst.l        D0
  1062.         beq        NoIFFHandle
  1063.  
  1064.         move.l        D0,A3
  1065.  
  1066. ;   IFFHandle->iff_Stream = Open("ENV:sys/icontrol.prefs",MODE_OLDFILE))
  1067.         move.l        _DOSBase(A4),A6
  1068.         lea        ICNTRLFILENAME(PC),A0
  1069.         move.l        A0,D1
  1070.         move.l        #MODE_OLDFILE,D2
  1071.         libcall     Open
  1072.  
  1073.         move.l        D0,iff_Stream(A3)
  1074.         beq        NoStream
  1075.  
  1076. ;   InitIFFasDOS(IFFHandle)
  1077.         move.l        A2,A6
  1078.         move.l        A3,A0
  1079.         libcall     InitIFFasDOS
  1080.  
  1081. ;   OpenIFF(IFFHandle,IFFF_READ)
  1082.         move.l        A3,A0
  1083.         moveq.l     #IFFF_READ,D0
  1084.         libcall     OpenIFF
  1085.  
  1086.         tst.l        D0
  1087.         bne        NoOpenIFF
  1088.  
  1089. ;   StopChunk(IFFHandle,ID_PREF,ID_ICTL);
  1090.         move.l        A3,A0
  1091.         move.l        #'PREF',D0
  1092.         move.l        #'ICTL',D1
  1093.         libcall     StopChunk
  1094.  
  1095. ;   ParseIFF(IFFHandle,IFFPARSE_SCAN)
  1096. ParseAgain:    move.l        A3,A0
  1097.         moveq.l     #IFFPARSE_SCAN,D0
  1098.         libcall     ParseIFF
  1099.  
  1100.         tst.l        D0
  1101.         beq        ParseOK
  1102.  
  1103.         addq.l        #-IFFERR_EOC,D0
  1104.         beq        ParseAgain
  1105.  
  1106.         bra        ParseError
  1107.  
  1108. ;   ReadChunkBytes(IFFHandle, &ICP, 0x12)
  1109. ParseOK:    lea        -TimeOutBytes(SP),SP
  1110.         move.l        A3,A0
  1111.         move.l        SP,A1
  1112.         moveq.l     #TimeOutBytes,D0
  1113.         libcall     ReadChunkBytes
  1114.  
  1115.         cmp.w        #TimeOutBytes,D0
  1116.         bne        ReadError
  1117.  
  1118.         move.w        ic_TimeOut(SP),D3
  1119.  
  1120. ReadError:    lea        TimeOutBytes(SP),SP
  1121.  
  1122. ;   CloseIFF(IFFHandle)
  1123. ParseError:    move.l        A3,A0
  1124.         libcall     CloseIFF
  1125.  
  1126. ;   Close(IFFHandle->iff_Stream)
  1127. NoOpenIFF    move.l        _DOSBase(A4),A6
  1128.         move.l        iff_Stream(A3),D1
  1129.         libcall     Close
  1130.  
  1131. ;   FreeIFF(IFFHandle)
  1132. NoStream:    move.l        A2,A6
  1133.         move.l        A3,A0
  1134.         libcall     FreeIFF
  1135.  
  1136. ;   CloseLibrary(IFFParseBase)
  1137. NoIFFHandle:    move.l        _ExecBase(A4),A6
  1138.         move.l        A2,A1
  1139.         libcall     CloseLibrary
  1140.  
  1141. ;   return TimeOut
  1142. NoIFFLib:    move.l        D3,D0
  1143.  
  1144.         movem.l     (SP)+,D2/D3/A2/A3/A6
  1145.         rts
  1146.  
  1147. ;************************************
  1148. ;* VOID PopUpHandler(CxMsg,CxObj)   *
  1149. ;*                    *
  1150. ;************************************
  1151. @PopUpHandler:    movem.l     D2/A2-A4/A6,-(SP)
  1152.         move.l        A0,A2
  1153.         move.l        CxBase,A6    ; can't use local here
  1154.  
  1155. ;   Get the data from the CxMsg
  1156.         libcall     CxMsgData    ; (A0=cxm)
  1157.  
  1158.         move.l        D0,A3    ; A3 = InputEvent
  1159.         move.l        A2,A0
  1160.         libcall     CxMsgID    ; (A0=cxm)
  1161.  
  1162.         move.l        D0,A4    ; A4 = InputData
  1163.  
  1164.         move.l        (AbsExecBase).w,A6
  1165.  
  1166. ;   Move the flags to a register for speed
  1167.         move.b        ssd_Flags(A4),D2
  1168.  
  1169. ;   Are the menus pop-up'ed now ?
  1170.         btst        #MENUS_ON_B,D2
  1171.         beq        NotOn
  1172.  
  1173. ;   Tell the PopUpMenu task that the input.device is alive
  1174.         move.l        ssd_PopUpMenuTask(A4),A1
  1175.         move.l        ssd_MouseMovedSig+ssi_Mask(A4),D0
  1176.         libcall     Signal        ; (A1=task,D0=signalSet)
  1177.  
  1178. ;   When the menus are displayed only RAWMOUSE events passes
  1179.         moveq.l     #IECLASS_RAWMOUSE,D0
  1180.         cmp.b        ie_Class(A3),D0
  1181.         bne        RemoveEvent
  1182.  
  1183. ;   Move the code to a register for speed
  1184.         move.w        ie_Code(A3),D1
  1185.  
  1186. ;   Selectbutton pressed ?
  1187.         cmpi.w        #SELECTDOWN,D1
  1188.         bne        CheckSelUp        ; No
  1189.  
  1190.         bset        #S_DOWN_B,D2
  1191.         move.l        ssd_SelectDownSig+ssi_Mask(A4),D0
  1192.         bra        SigAndRemove    ; dont care about qualifiers
  1193.  
  1194. ;   Selectbutton released ?
  1195. CheckSelUp:    cmpi.w        #SELECTUP,D1
  1196.         bne        CheckMenuUp     ; No
  1197.  
  1198.         bclr        #S_DOWN_B,D2
  1199.         move.l        ssd_SelectUpSig+ssi_Mask(A4),D0
  1200.         bra        SigAndRemoveQ    ; qualifiers needed for clickmenus
  1201.  
  1202. ;   Menu-button released ?
  1203. CheckMenuUp:    cmpi.w        #MENUUP,D1
  1204.         bne        CheckMenuDown    ; No
  1205.  
  1206.         bclr        #M_DOWN_B,D2
  1207.  
  1208. ;   Menu operation stops only if CLICKON is set
  1209.         btst        #CLICKON_B,D2
  1210.         beq        RemoveEvent
  1211.  
  1212.         bclr        #CLICKON_B,D2
  1213.         bclr        #MENUS_ON_B,D2
  1214.         move.l        ssd_MenuUpSig+ssi_Mask(A4),D0
  1215.         bra        SigAndRemoveQ    ; qualifiers needed
  1216.  
  1217. ;   Menu-button pressed ?
  1218. CheckMenuDown:    cmpi.w        #MENUDOWN,D1
  1219.         bne        KeepEvent        ; No
  1220.  
  1221.         bset        #M_DOWN_B,D2
  1222.         bset        #CLICKON_B,D2
  1223.         bra        RemoveEvent
  1224.  
  1225. ;   Menus are not pop-up'ed
  1226. ;
  1227. NotOn:        moveq.l     #IECLASS_RAWMOUSE,D0
  1228.         cmp.b        ie_Class(A3),D0
  1229.         bne        KeepEvent
  1230.  
  1231. ;   Move code to register for speed
  1232.         move.w        ie_Code(A3),D1
  1233.  
  1234. ;   SelectButton released ?  We only care if it was down when
  1235. ;   the menuoperation was finished.
  1236.         cmpi.w        #SELECTUP,D1
  1237.         bne        1$
  1238.  
  1239.         btst        #S_DOWN_B,D2
  1240.         beq        KeepEvent
  1241.  
  1242.         bclr        #S_DOWN_B,D2
  1243.         bra        RemoveEvent
  1244.  
  1245. ;   Menu-button released ?
  1246. 1$        cmpi.w        #MENUUP,D1
  1247.         bne        2$
  1248.  
  1249.         btst        #M_DOWN_B,D2
  1250.         beq        KeepEvent
  1251.  
  1252.         bclr        #M_DOWN_B,D2
  1253.         bra        RemoveEvent
  1254.  
  1255. ;   Menu-button pressed ?
  1256. 2$        cmpi.w        #MENUDOWN,D1
  1257.         bne        KeepEvent        ; No
  1258.  
  1259. ;   No menus if any other mousebutton is pressed
  1260. MenuPressed:    move.w        ie_Qualifier(A3),D1
  1261.         move.w        #IEQUALIFIER_MIDBUTTON+IEQUALIFIER_LEFTBUTTON,D0
  1262.         and.w        D1,D0
  1263.         bne        KeepEvent
  1264.  
  1265. ;   Are any other qalifiers pressed ?
  1266.         move.w        #QUALIFIERS,D0
  1267.         and.w        D1,D0
  1268.         beq        1$            ; No
  1269.  
  1270. ;   Should we pop-up the menus with qualifier ?
  1271.         btst        #POPUPWITHQUAL_B0,ssd_Options(A4)
  1272.         beq        KeepEvent        ; No
  1273.         bra        QualifierOk
  1274.  
  1275. ;   Should we pop-up the menus without qualifiers ?
  1276. 1$        btst        #POPUPNOQUAL_B0,ssd_Options(A4)
  1277.         beq        KeepEvent        ; No
  1278.  
  1279. ;   Menu-button pressed and we should pop-up the menus.
  1280. ;   Do we have an active screen to put the menus on ?
  1281. QualifierOk:    move.l        IBase,A1
  1282.         move.l        ib_ActiveScreen(A1),A0
  1283.         move.l        A0,D0
  1284.         beq        KeepEvent        ; No
  1285.  
  1286. ;   Is the mouse in the titlebar ? [if so, use standard menus]
  1287.         move.b        sc_BarHeight(A0),D0
  1288.         ext.w        D0
  1289.         cmp.w        sc_MouseY(A0),D0
  1290.         bgt        KeepEvent        ; Yes
  1291.  
  1292. ;   Do we have an active window on the screen ?
  1293.         move.l        ib_ActiveWindow(A1),A0
  1294.         move.l        A0,D0
  1295.         beq        KeepEvent        ; No
  1296.  
  1297. ;   Is a requester blocking the window ?
  1298. ;   (RKM says we shouldn't trust the ReqCount field, but what to do ?)
  1299.         tst.w        wd_ReqCount(A0)
  1300.         bne        KeepEvent        ; Yes
  1301.  
  1302. ;   Does the window have menus ?
  1303.         tst.l        wd_MenuStrip(A0)
  1304.         beq        KeepEvent        ; No
  1305.  
  1306. ;   Is the RMBTRAP flag set ?
  1307.         btst        #WFLG_RMBTRAP_B1,wd_Flags+1(A0)
  1308.         bne        KeepEvent        ; Yes
  1309.  
  1310. ;   Everything is OK, set flags
  1311.         bset        #MENUS_ON_B,D2
  1312.         bset        #M_DOWN_B,D2
  1313.  
  1314. ;   If we are using clickmenus, menu-button must be relased twice
  1315.         btst        #CLICKMENUS_B0,ssd_Options(A4)
  1316.         bne        1$
  1317.  
  1318. ;   Otherwise once is enough
  1319.         bset        #CLICKON_B,D2
  1320.  
  1321. ;   Tell the popupmenu task to popup the menus.
  1322. 1$        move.l        ssd_MenuDownSig+ssi_Mask(A4),D0
  1323.  
  1324. ;   Save the qualifiers pressed now
  1325. SigAndRemoveQ:    move.w        ie_Qualifier(A3),ssd_EndQualifier(A4)
  1326.  
  1327. ;   Signal to the PopUpMenu task
  1328. SigAndRemove:    move.l        ssd_PopUpMenuTask(A4),A1
  1329.         libcall     Signal        ; (A1=task,D0=signalSet)
  1330.  
  1331. ;   Remove the event from the input stream
  1332. RemoveEvent:    move.l        CxBase,A6
  1333.         move.l        A2,A0
  1334.         libcall     DisposeCxMsg    ; (A0=cxm)
  1335.  
  1336. KeepEvent:    move.b        D2,ssd_Flags(A4)
  1337.  
  1338.         movem.l     (SP)+,D2/A2-A4/A6
  1339.         rts
  1340.  
  1341. ;********************************************
  1342. ;* MyClearMenuStrip,                *
  1343. ;* MyOnMenu, MyOffMenu                *
  1344. ;*                        *
  1345. ;* My replacements for intuition functions. *
  1346. ;********************************************
  1347. @MyClearMenuStrip:
  1348.         lea        OldClearMenuStrip(PC),A1
  1349.         bra        CallOldFunction
  1350.  
  1351. @MyOnMenu:    lea        OldOnMenu(PC),A1
  1352.         bra        CallOldFunction
  1353.  
  1354. @MyOffMenu:    lea        OldOffMenu(PC),A1
  1355.  
  1356. ;    Obtain our semaphore and then call the intuition function.
  1357. CallOldFunction:
  1358.         move.l        A6,-(SP)
  1359.         movem.l     D0/A0-A1/A6,-(SP)
  1360.         move.l        (AbsExecBase).w,A6
  1361.  
  1362. ;    We use shared access here so multiple tasks can use it
  1363.         lea        PopUpSemaphore(PC),A0
  1364.         libcall     ObtainSemaphoreShared ; (A0=sigSem)
  1365.  
  1366.         movem.l     (SP)+,D0/A0-A1/A6
  1367.         move.l        (A1),A1
  1368.         jsr        (A1)
  1369.         move.l        (AbsExecBase).w,A6
  1370.  
  1371.         lea        PopUpSemaphore(PC),A0
  1372.         libcall     ReleaseSemaphore     ; (A0=sigSem)
  1373.  
  1374.         move.l        (SP)+,A6
  1375.         rts
  1376.  
  1377. ;************************************************
  1378. ;* VOID QueTimer(UWORD Length) - Start a timer  *
  1379. ;*                        *
  1380. ;* Input:                    *
  1381. ;*   Length  - Length before timer in VBLANKS    *
  1382. ;* Output:                    *
  1383. ;*   none                    *
  1384. ;************************************************
  1385. @QueTimer:    move.l        A6,-(SP)
  1386.         move.l        _TimerReqBlock(A4),A1
  1387.  
  1388. ;   TimerReqBlock->tr_node.io_Command = TR_ADDREQUEST
  1389.         move.w        #TR_ADDREQUEST,IO_COMMAND(A1)
  1390.  
  1391. ;   TimerReqBlock->tr_time.tv_secs = 0;
  1392.         clr.l        IOTV_TIME+TV_SECS(A1)
  1393.  
  1394. ;   TimerReqBlock->tr_time.tv_micro = Length*20000    [20000 micros == 1 VBLANK]
  1395.         mulu.w        #20000,D0
  1396.         move.l        D0,IOTV_TIME+TV_MICRO(A1)
  1397.  
  1398. ;   SendIO(TimerReqBlock);
  1399.         move.l        _ExecBase(A4),A6
  1400.         libcall     SendIO    ; (A1=ioRequest)
  1401.  
  1402.         move.l        (SP)+,A6
  1403.         rts
  1404.  
  1405. ;**************************
  1406. ;* VOID AbortTimer(VOID)  *
  1407. ;**************************
  1408. @AbortTimer:    move.l        A2,-(SP)
  1409.         move.l        A6,-(SP)
  1410.         move.l        _ExecBase(A4),A6
  1411.         move.l        _TimerReqBlock(A4),A2
  1412.  
  1413. ;   Any timer going on ?     [ CheckIO(TimerReqBlock) ]
  1414.         move.l        A2,A1
  1415.         libcall     CheckIO
  1416.  
  1417.         tst.l        D0
  1418.         bne        NoTimerRunning
  1419.  
  1420. ;   Abort the timer   [ AbortIO(TimerReqBlock) ]
  1421.         move.l        A2,A1
  1422.         libcall     AbortIO
  1423.  
  1424. ;   Wait for abort message  [ WaitIO(TimerReqBlock) ]
  1425.         move.l        A2,A1
  1426.         libcall     WaitIO
  1427.  
  1428. ;   Remove timersignal     [ SetSignal(0,TimerSigMask) ]
  1429.         moveq.l     #0,D0
  1430.         move.l        _TimerSigMask(A4),D1
  1431.         libcall     SetSignal        ; (D0=newSignals,D1=signalMask)
  1432.  
  1433. NoTimerRunning: move.l        (SP)+,A6
  1434.         move.l        (SP)+,A2
  1435.         rts
  1436.  
  1437. ;************************************************************
  1438. ;* UBYTE ParseArgs(VOID)   get user arguments both CLI & WB *
  1439. ;*                                *
  1440. ;* Input                            *
  1441. ;*   none                            *
  1442. ;* Output                            *
  1443. ;*   return    Options                        *
  1444. ;*   D1        Broker priority                    *
  1445. ;************************************************************
  1446.         STRUCTURE   Args,0
  1447.         ULONG        arg_ClickMenus
  1448.         ULONG        arg_ShowSingle
  1449.         ULONG        arg_CenterItems
  1450.         ULONG        arg_PopWithQual
  1451.         ULONG        arg_PopUp
  1452.         APTR        arg_PopKey
  1453.         LONG        arg_Pri
  1454.         LABEL        arg_SIZEOF
  1455.  
  1456. @ParseArgs:    movem.l     D2-D5/A2-A3/A6,-(SP)
  1457.  
  1458. ;    Workbench or cli arguments ?
  1459.         lea        DefaultArgs(PC),A2
  1460.         tst.l        _WBenchMsg(A4)
  1461.         bne        GetWBArgs
  1462.  
  1463. ;    Rda = ReadArgs(Template,&DefaultArgs,NULL)
  1464. GetCLIArgs:    move.l        _DOSBase(A4),A6
  1465.         lea        TEMPLATETEXT(PC),A0
  1466.         move.l        A0,D1
  1467.         move.l        A2,D2
  1468.         moveq.l     #0,D3
  1469.         libcall     ReadArgs
  1470.  
  1471.         move.l        D0,D2
  1472.  
  1473. ;   IconBase = OldCD = DiskObj = 0
  1474. ;[Not needed]    moveq.l     #0,D3
  1475.         moveq.l     #0,D4
  1476.         moveq.l     #0,D5
  1477.         bra        GetArgDone
  1478.  
  1479. ;   Open icon library, any version will do
  1480. GetWBArgs:    move.l        _ExecBase(A4),A6
  1481.         lea        ICONNAME(PC),A1
  1482.         moveq.l     #0,D0
  1483.         libcall     OpenLibrary     ; (A1=libName,D0=version)
  1484.  
  1485.         move.l        D0,D3
  1486.         beq        GetArgDone
  1487.  
  1488. ;    OldCD = CurrentDir(WBenchMsg->sm_ArgList->wa_Lock)
  1489.         move.l        _DOSBase(A4),A6
  1490.         move.l        _WBenchMsg(A4),A3
  1491.         move.l        sm_ArgList(A3),A3
  1492.         move.l        wa_Lock(A3),D1
  1493.         libcall     CurrentDir        ; (D1=lock)
  1494.  
  1495.         move.l        D0,D4
  1496.  
  1497. ;    DiskObj = GetDiskObject(WBenchMsg->sm_ArgList->wa_Name)
  1498.         move.l        D3,A6        ; IconBase
  1499.         move.l        wa_Name(A3),A0
  1500.         libcall     GetDiskObject    ; (a0=name)
  1501.  
  1502.         move.l        D0,D5
  1503.         beq        GetArgDone
  1504.  
  1505. ;    ToolTypes = Dobj->do_ToolTypes
  1506.         move.l        D0,A0
  1507.         move.l        do_ToolTypes(A0),A3
  1508.  
  1509. ;  D2 = Rda
  1510. ;  D3 = IconBase     A2 = DefaultArgs
  1511. ;  D4 = OldCD         A3 = ToolTypes
  1512. ;  D5 = DiskObject   A6 = IconBase
  1513.  
  1514. ;  DefaultArgs.ClickMenus = FindToolType(ToolTypes,"CLICKMENUS")
  1515.         move.l        A3,A0
  1516.         lea        ARG_CLICK(PC),A1
  1517.         libcall     FindToolType
  1518.  
  1519.         move.l        D0,arg_ClickMenus(A2)
  1520.  
  1521. ;  DefaultArgs.ShowSingle = FindToolType(ToolTypes,"SHOWSINGLE")
  1522.         move.l        A3,A0
  1523.         lea        ARG_SHOW(PC),A1
  1524.         libcall     FindToolType
  1525.  
  1526.         move.l        D0,arg_ShowSingle(A2)
  1527.  
  1528. ;   DefaultArgs.CenterItems = FindToolType(ToolTypes,"CENTERITEMS")
  1529.         move.l        A3,A0
  1530.         lea        ARG_CENTER(PC),A1
  1531.         libcall     FindToolType
  1532.  
  1533.         move.l        D0,arg_CenterItems(A2)
  1534.  
  1535. ;   DefaultArgs.PopWithQual = FindToolType(ToolTypes,"POPWITHQUAL")
  1536.         move.l        A3,A0
  1537.         lea        ARG_POPWITH(PC),A1
  1538.         libcall     FindToolType
  1539.  
  1540.         move.l        D0,arg_PopWithQual(A2)
  1541.  
  1542. ;   Value = FindToolType(ToolTypes,"CX_POPUP")
  1543.         move.l        A3,A0
  1544.         lea        ARG_CXPOPUP(PC),A1
  1545.         libcall     FindToolType
  1546.  
  1547.         tst.l        D0
  1548.         beq        1$
  1549.  
  1550. ;   DefaultArgs.PopUp = MatchToolValue(Value,"YES")
  1551.         move.l        D0,A0
  1552.         lea        YESTEXT(PC),A1
  1553.         libcall     MatchToolValue
  1554.  
  1555.         move.l        D0,arg_PopUp(A2)
  1556.  
  1557. ;   Value = FindToolType(ToolTypes,"CX_POPKEY")
  1558. 1$        move.l        A3,A0
  1559.         lea        ARG_CXPOPKEY(PC),A1
  1560.         libcall     FindToolType
  1561.  
  1562.         tst.l        D0
  1563.         beq        2$
  1564.  
  1565. ;    DefaultArgs.PopKey = Value
  1566.         move.l        D0,arg_PopKey(A2)
  1567.  
  1568. ;    Value = FindToolType(ToolTypes,"CX_PRIORITY")
  1569. 2$        move.l        A3,A0
  1570.         lea        ARG_CXPRI(PC),A1
  1571.         libcall     FindToolType
  1572.  
  1573.         move.l        D0,D1
  1574.         beq        3$
  1575.  
  1576. ;    StrToLong(Value,DefaultArgs.Pri);
  1577.         move.l        _DOSBase(A4),A6
  1578.         lea        arg_Pri(A2),A0
  1579.         move.l        A0,D2
  1580.         libcall     StrToLong
  1581.  
  1582.         move.l        D3,A6        ; restore IconBase
  1583.  
  1584. ;   Rda = 0
  1585. 3$        moveq.l     #0,D2
  1586.  
  1587. GetArgDone:    moveq.l     #POPUPNOQUAL,D0
  1588.         tst.l        (A2)+
  1589.         beq        1$
  1590.         bset        #CLICKMENUS_B0,D0
  1591. 1$        tst.l        (A2)+
  1592.         beq        2$
  1593.         bset        #SHOWSINGLEMENU_B0,D0
  1594. 2$        tst.l        (A2)+
  1595.         beq        3$
  1596.         bset        #ITEMSCENTERED_B0,D0
  1597. 3$        tst.l        (A2)+
  1598.         beq        4$
  1599.         bset        #POPUPWITHQUAL_B0,D0
  1600. 4$        tst.l        (A2)+
  1601.         beq        5$
  1602.         bset        #OPENOPTWINDOW_B0,D0
  1603. 5$        move.l        (A2)+,A0
  1604.         lea        _HotKeyString(A4),A1
  1605. 6$        move.b        (A0)+,(A1)+
  1606.         bne        6$
  1607.         move.l        (A2),A2         ; CX_PRIORITY
  1608.  
  1609.         exg.l        D0,D5
  1610.  
  1611. ;  if (DiskObj) FreeDiskObject(DiskObj)
  1612.         tst.l        D0
  1613.         beq        RestoreCD
  1614.  
  1615.         move.l        D0,A0
  1616.         libcall     FreeDiskObject
  1617.  
  1618. ;  if (OldCD)  CurrentDir(OldCD)
  1619. RestoreCD:    move.l        _DOSBase(A4),A6
  1620.         move.l        D4,D1
  1621.         beq        FreeArg
  1622.  
  1623.         libcall     CurrentDir         ; (D1=lock)
  1624.  
  1625. ;  if (Rda) FreeArgs(Rda)
  1626. FreeArg:    move.l        D2,D1
  1627.         beq        CloseLib
  1628.  
  1629.         libcall     FreeArgs
  1630.  
  1631. ;  if (IconBase)  CloseLibrary(IconBase)
  1632. CloseLib:    tst.l        D3
  1633.         beq        1$
  1634.  
  1635.         move.l        _ExecBase(A4),A6
  1636.         move.l        D3,A1
  1637.         libcall     CloseLibrary     ; (A1=library)
  1638.  
  1639. 1$        move.l        D5,D0         ; Options
  1640.         move.l        (A2),D1          ; Priority
  1641.         movem.l     (SP)+,D2-D5/A2-A3/A6
  1642.         rts
  1643.  
  1644. ;***********************************************************************
  1645. ;* VOID MyDeletePort(Port) -  Reply to all pending messages and delete *
  1646. ;*                                       *
  1647. ;* Input:                                   *
  1648. ;*   Port  - the port to delete                        *
  1649. ;***********************************************************************
  1650. @MyDeletePort:    move.l        A2,-(SP)
  1651.         move.l        A6,-(SP)
  1652.         move.l        A0,A2
  1653.         move.l        _ExecBase(A4),A6
  1654. 1$        move.l        A2,A0
  1655.         libcall     GetMsg    ; (A0=port)
  1656.  
  1657.         tst.l        D0
  1658.         beq        2$        ; Port is empty
  1659.         move.l        D0,A1
  1660.         libcall     ReplyMsg    ; (A1=message)
  1661.  
  1662.         bra        1$
  1663. 2$        move.l        A2,A0
  1664.         libcall     DeleteMsgPort ; (A0=port)
  1665.  
  1666.         move.l        (SP)+,A6
  1667.         move.l        (SP)+,A2
  1668.         rts
  1669.  
  1670. ;****************************************************************
  1671. ;* ULONG OpenOptWindow(ULONG WindowSig)  - Open option window   *
  1672. ;*                                *
  1673. ;* Input:                            *
  1674. ;*   WindowSig     - Current windowsignal or 0 if window not open *
  1675. ;* Output:                            *
  1676. ;*   return     - Window signal                *
  1677. ;****************************************************************
  1678. HIDE        equ        1
  1679. KILL        equ        -1
  1680.  
  1681. @OpenOptWindow: movem.l     D2-D3/A2-A3/A5-A6,-(SP)
  1682.         tst.l        D0
  1683.         beq        ReallyOpen
  1684.  
  1685. ;   Window is already open, move it to front
  1686.         move.l        D0,D2     ; save signal bit
  1687.         move.l        _IntuitionBase(A4),A6
  1688.  
  1689.         move.l        _OptWindow(A4),A0
  1690.         libcall     WindowToFront    ; (A0=window)
  1691.  
  1692.         move.l        _OptWindow(A4),A0
  1693.         libcall     ActivateWindow    ; (A0=window)
  1694.  
  1695.         move.l        D2,D0     ; return same bit
  1696.         bra        OpenOptDone
  1697.  
  1698. ;   Create local variables
  1699. ReallyOpen:    lea        -gng_SIZEOF(SP),SP
  1700.  
  1701. ;   Open library
  1702.         move.l        _ExecBase(A4),A6
  1703.         lea        GADTOOLSNAME(PC),A1
  1704.         moveq.l     #KICK204,D0
  1705.         libcall     OpenLibrary     ; (A1=libName,D0=version)
  1706.  
  1707.         move.l        D0,_GadToolsBase(A4)
  1708.         beq        NoGadToolsLib
  1709.  
  1710. ;   Find the default screen
  1711.         move.l        _IntuitionBase(A4),A6
  1712.         lea        WindowTags(PC),A3     ; A3 = Windowtags
  1713.         suba.l        A0,A0
  1714.         libcall     LockPubScreen      ; (A0=name)
  1715.  
  1716.         move.l        D0,wtag_PubScreen(A3)
  1717.         beq        NoPubScreen
  1718.  
  1719. ;   Find size of window title bar
  1720.         move.l        D0,A0
  1721.         moveq.l     #0,D0
  1722.         move.b        sc_WBorTop(A0),D0
  1723.         move.l        sc_Font(A0),A1
  1724.         add.w        ta_YSize(A1),D0
  1725.         addq.w        #1,D0
  1726.         move.w        D0,gng_TopEdge(SP)
  1727.  
  1728. ;   Get visual info
  1729.         move.l        _GadToolsBase(A4),A6
  1730.         lea        TagDone(PC),A1
  1731.         libcall     GetVisualInfoA    ; (A0=screen,A1=taglist)
  1732.  
  1733.         move.l        D0,gng_VisualInfo(SP)
  1734.         move.l        D0,_VisualInfo(A4)
  1735.         beq        NoVisualInfo
  1736.  
  1737. ;   Init the NewGadget structure
  1738. ;   Set font = Topaz 8
  1739.         lea        Topaz8Font(PC),A0
  1740.         move.l        A0,gng_TextAttr(SP)
  1741.  
  1742. ;   ID = 0..N
  1743.         clr.w        gng_GadgetID(SP)
  1744.  
  1745. ;   LeftEdge is same for first three gadgets
  1746.         move.w        #32,gng_LeftEdge(SP)
  1747.  
  1748. ;   Width and height is ignored in CHECKBOX gadgets, set them anyway
  1749.         move.l        #$001a000b,gng_Width(SP)  ; Both width and height
  1750.  
  1751. ;   Same gadgets in the first 5 gadgets
  1752.         lea        CheckBoxTags(PC),A2
  1753.  
  1754. ;   Checkmark items depending on option status
  1755.         move.b        _CxHandlerData+ssd_Options(A4),D3
  1756.  
  1757. ;   Create a context to use
  1758.         lea        wtag_Gadgets(A3),A0
  1759.         clr.l        (A0)
  1760.         libcall     CreateContext    ; (A0=glistptr)
  1761.  
  1762.         lea        _Gadgets(A4),A5
  1763.  
  1764. ;   Gadget 0 (clickmenus)
  1765.         move.l        SP,A1           ; A1 = NewGadget
  1766.         lea        CLICKTEXT(PC),A0
  1767.         move.l        A0,gng_GadgetText(A1)
  1768.         move.l        D0,A0
  1769.         addq.w        #4,gng_TopEdge(A1)
  1770.  
  1771.         moveq.l     #CLICKMENUS,D0
  1772.         and.l        D3,D0
  1773.         move.l        D0,12(A2)
  1774.  
  1775.         moveq.l     #PLACETEXT_RIGHT,D0
  1776.         move.l        D0,gng_Flags(A1)
  1777.         moveq.l     #CHECKBOX_KIND,D0
  1778.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1779.  
  1780.         move.l        D0,(A5)+
  1781.  
  1782. ;   Gadget 1 (show single)
  1783.         move.l        SP,A1           ; A1 = NewGadget
  1784.         lea        SINGLETEXT(PC),A0
  1785.         move.l        A0,gng_GadgetText(A1)
  1786.         move.l        D0,A0
  1787.         add.w        #11,gng_TopEdge(A1)
  1788.         addq.w        #1,gng_GadgetID(A1)
  1789.  
  1790.         moveq.l     #SHOWSINGLEMENU,D0
  1791.         and.l        D3,D0
  1792.         move.l        D0,12(A2)
  1793.  
  1794.         moveq.l     #CHECKBOX_KIND,D0
  1795.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1796.  
  1797.         move.l        D0,(A5)+
  1798.  
  1799. ;   Gadget 2 (centered items)
  1800.         move.l        SP,A1           ; A1 = NewGadget
  1801.         lea        CENTEREDTEXT(PC),A0
  1802.         move.l        A0,gng_GadgetText(A1)
  1803.         move.l        D0,A0
  1804.  
  1805.         add.w        #11,gng_TopEdge(A1)
  1806.         addq.w        #1,gng_GadgetID(A1)
  1807.  
  1808.         moveq.l     #ITEMSCENTERED,D0
  1809.         and.l        D3,D0
  1810.         move.l        D0,12(A2)
  1811.  
  1812.         moveq.l     #CHECKBOX_KIND,D0
  1813.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1814.  
  1815.         move.l        D0,(A5)+
  1816.  
  1817. ;   Gadget 3 (with qualifier)
  1818.         move.l        SP,A1           ; A1 = NewGadget
  1819.         lea        WITHTEXT(PC),A0
  1820.         move.l        A0,gng_GadgetText(A1)
  1821.         move.l        D0,A0
  1822.  
  1823.         add.w        #14,gng_TopEdge(A1)
  1824.         move.w        #119,gng_LeftEdge(A1)
  1825.         addq.w        #1,gng_GadgetID(A1)
  1826.  
  1827.         moveq.l     #POPUPWITHQUAL,D0
  1828.         and.l        D3,D0
  1829.         move.l        D0,12(A2)
  1830.  
  1831.         moveq.l     #CHECKBOX_KIND,D0
  1832.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1833.  
  1834.         move.l        D0,(A5)+
  1835.  
  1836. ;   Gadget 4 (without qualifier)
  1837.         move.l        SP,A1           ; A1 = NewGadget
  1838.         lea        WITHOUTTEXT(PC),A0
  1839.         move.l        A0,gng_GadgetText(A1)
  1840.         move.l        D0,A0
  1841.  
  1842.         add.w        #11,gng_TopEdge(A1)
  1843.         addq.w        #1,gng_GadgetID(A1)
  1844.  
  1845.         moveq.l     #POPUPNOQUAL,D0
  1846.         and.l        D3,D0
  1847.         move.l        D0,12(A2)
  1848.  
  1849.         moveq.l     #CHECKBOX_KIND,D0
  1850.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1851.  
  1852.         move.l        D0,(A5)+
  1853.  
  1854. ;   Gadget 5 (hotkey)
  1855.         lea        StringTags(PC),A2
  1856.  
  1857.         move.l        SP,A1           ; A1 = NewGadget
  1858.         lea        HOTKEYTEXT(PC),A0
  1859.         move.l        A0,gng_GadgetText(A1)
  1860.         lea        _HotKeyString(A4),A0     ; Deafult hotkey
  1861.         move.l        A0,4(A2)
  1862.         move.l        D0,A0
  1863.  
  1864.         moveq.l     #PLACETEXT_LEFT,D0
  1865.         move.l        D0,gng_Flags(A1)
  1866.  
  1867.         move.w        #72,gng_LeftEdge(A1)
  1868.         add.w        #14,gng_TopEdge(A1)
  1869.         move.l        #$00ce000d,gng_Width(A1) ; Both width and height
  1870.         addq.w        #1,gng_GadgetID(A1)
  1871.  
  1872.         moveq.l     #STRING_KIND,D0
  1873.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1874.  
  1875.         move.l        D0,(A5)                  ; last gadget remembered use
  1876.  
  1877. ;   Gadget 6 (Kill)
  1878.         lea        ButtonTags(PC),A2
  1879.  
  1880.         move.l        SP,A1           ; A1 = NewGadget
  1881.         lea        KILLTEXT(PC),A0
  1882.         move.l        A0,gng_GadgetText(A1)
  1883.         move.l        D0,A0
  1884.  
  1885.         moveq.l     #PLACETEXT_IN,D0
  1886.         move.l        D0,gng_Flags(A1)
  1887.  
  1888.         move.w        #20,gng_LeftEdge(A1)
  1889.         add.w        #18,gng_TopEdge(A1)
  1890.         move.l        #$0039000c,gng_Width(A1) ; Both width and height
  1891.  
  1892.         addq.w        #1,gng_GadgetID(A1)
  1893.  
  1894.         moveq.l     #BUTTON_KIND,D0
  1895.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1896.  
  1897. ;   Gadget 7 (hide)
  1898.         move.l        SP,A1           ; A1 = NewGadget
  1899.  
  1900.         lea        HIDETEXT(PC),A0
  1901.         move.l        A0,gng_GadgetText(A1)
  1902.         move.l        D0,A0
  1903.  
  1904.         move.w        #220,gng_LeftEdge(A1)
  1905.         addq.w        #1,gng_GadgetID(A1)
  1906.  
  1907.         moveq.l     #BUTTON_KIND,D0
  1908.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1909.  
  1910. ;   Gadget 7(!) (text)
  1911.         move.l        SP,A1           ; A1 = NewGadget
  1912.  
  1913.         lea        TEXTTEXT(PC),A0
  1914.         move.l        A0,gng_GadgetText(A1)
  1915.         move.l        D0,A0
  1916.  
  1917.         move.w        #119,gng_LeftEdge(A1)
  1918.         sub.w        #38,gng_TopEdge(A1)
  1919.  
  1920.         moveq.l     #PLACETEXT_LEFT,D0
  1921.         move.l        D0,gng_Flags(A1)
  1922.  
  1923.         moveq.l     #TEXT_KIND,D0
  1924.         libcall     CreateGadgetA    ; (D0=kind,A0=gad,A1=ng,A2=taglist)
  1925.  
  1926.         tst.l        D0
  1927.         beq        NoGad
  1928.  
  1929. ;   open window
  1930.         move.l        _IntuitionBase(A4),A6
  1931.         suba.l        A0,A0
  1932.         move.l        A3,A1        ; WindowTags
  1933.         libcall     OpenWindowTagList    ; (A0=newWindow,A1=tagList)
  1934.  
  1935.         move.l        D0,_OptWindow(A4)
  1936.  
  1937.         beq        NoWindow
  1938.  
  1939. ;   Draw the gadgets
  1940.         move.l        _GadToolsBase(A4),A6
  1941.         move.l        D0,A0        ; Window
  1942.         sub.l        A1,A1
  1943.         libcall     GT_RefreshWindow    ; (A0=win,A1=req)
  1944.  
  1945. ;   Find the signalbit
  1946.         move.l        _OptWindow(A4),A0
  1947.         move.l        wd_UserPort(A0),A0
  1948.         moveq.l     #0,D1
  1949.         move.b        MP_SIGBIT(A0),D1
  1950.         moveq.l     #1,D0
  1951.         lsl.l        D1,D0
  1952.         bra        OpenOk
  1953.  
  1954. NoWindow:    move.l        _GadToolsBase(A4),A6
  1955. NoGad:        move.l        wtag_Gadgets(A3),A0
  1956.         libcall     FreeGadgets     ; (A0=gad)
  1957.  
  1958.         move.l        _VisualInfo(A4),A0
  1959.         libcall     FreeVisualInfo    ; (A0=vi)
  1960.  
  1961. NoVisualInfo:    move.l        wtag_PubScreen(A3),A1
  1962.         sub.l        A0,A0
  1963.         move.l        _IntuitionBase(A4),A6
  1964.         libcall     UnlockPubScreen        ; (A0=name,A1=screen)
  1965.  
  1966. NoPubScreen:    move.l        _GadToolsBase(A4),A1
  1967.         move.l        _ExecBase(A4),A6
  1968.         libcall     CloseLibrary    ; (A1=library)
  1969.  
  1970. NoGadToolsLib:    moveq.l     #0,D0
  1971.  
  1972. OpenOk:     lea        gng_SIZEOF(SP),SP
  1973.  
  1974. OpenOptDone:    movem.l     (SP)+,D2-D3/A2-A3/A5-A6
  1975.         rts
  1976.  
  1977. ;****************************************************************
  1978. ;* UWORD HandleOptWindow(VOID) - handle message from opt window *
  1979. ;*                                *
  1980. ;* Output:                            *
  1981. ;*   return    -  0  Nothing special                *
  1982. ;*         -1  User selected KILL             *
  1983. ;*          1  User selected HIDE (or closewindow)        *
  1984. ;****************************************************************
  1985. @HandleOptWindow:
  1986.         movem.l     D2-D4/A2-A3/A5-A6,-(SP)
  1987.         moveq.l     #0,D4    ; RetCode = 0
  1988.  
  1989. NextMessage:    move.l        _GadToolsBase(A4),A6
  1990.         move.l        _OptWindow(A4),A5
  1991.         move.l        wd_UserPort(A5),A0
  1992.         libcall     GT_GetIMsg        ; (A0=iport)
  1993.  
  1994.         tst.l        D0
  1995.         beq        NoMoreMessages
  1996.  
  1997.         move.l        D0,A1
  1998.         move.l        im_Class(A1),D2
  1999.         move.w        im_Code(A1),D3
  2000.         move.l        im_IAddress(A1),A2
  2001.  
  2002.         libcall     GT_ReplyIMsg    ; (A1=imsg)
  2003.  
  2004.         btst        #IDCMP_VANILLAKEY_B1+16,D2
  2005.         beq        CheckClose
  2006.  
  2007.         lea        KeyData(PC),A0
  2008.         moveq.l     #NoOfKeys-1,D1
  2009. 1$        cmp.b        (A0),D3
  2010.         beq        2$
  2011.         addq.l        #2,A0
  2012.         dbra        D1,1$
  2013.  
  2014.         move.l        _IntuitionBase(A4),A6
  2015.         lea        WindowTags(PC),A0
  2016.         move.l        wtag_PubScreen(A0),A0
  2017.         libcall     DisplayBeep
  2018.  
  2019.         bra        NextMessage       ; Key not handled
  2020.  
  2021. ;     Find corresponding gadget
  2022. 2$        moveq.l     #0,D0
  2023.         move.b        1(A0),D0
  2024.         move.b        D0,D2
  2025.         lsl.w        #2,D0
  2026.  
  2027. ;    Gadget is only valid if GadNr <= 5
  2028.         move.l        _Gadgets(A4,D0.w),A0
  2029.  
  2030.         cmp.b        #5,D2
  2031.         bcc        3$           ; bhs
  2032.  
  2033. ;    Toggle gadgets
  2034.         lea        CheckedTags(PC),A3
  2035.         moveq.l     #1,D0
  2036.         lsl.w        D2,D0           ; D0 = Option bit
  2037.         move.b        _CxHandlerData+ssd_Options(A4),D1
  2038.         eor.b        D0,D1           ; toggle option bit
  2039.         move.b        D1,_CxHandlerData+ssd_Options(A4)
  2040.         and.b        D1,D0
  2041.         move.l        D0,4(A3)
  2042.         sub.l        A2,A2
  2043.         move.l        A5,A1
  2044.         libcall     GT_SetGadgetAttrsA ; (A0=gad,A1=win,A2=req,A3=taglist)
  2045.  
  2046.         bra        NextMessage
  2047.  
  2048. 3$        bne        CheckButtons
  2049.  
  2050. ;   Hotkey
  2051.         move.l        _IntuitionBase(A4),A6
  2052.         move.l        A5,A1
  2053.         sub.l        A2,A2
  2054.         libcall     ActivateGadget    ; (A0=gadgets,A1=window,A2=requester)
  2055.  
  2056.         bra        NextMessage
  2057.  
  2058. CheckButtons:    subq.w        #6,D2
  2059.         bne        HideWindow
  2060.  
  2061. ;   Kill
  2062.         moveq.l     #KILL,D4
  2063.         bra        NextMessage
  2064.  
  2065. CheckClose:    btst        #IDCMP_CLOSEWINDOW_B2+8,D2
  2066.         beq        CheckGadgetUp
  2067.  
  2068. ;   Hide
  2069. HideWindow:    moveq.l     #HIDE,D4
  2070.         bra        NextMessage
  2071.  
  2072. CheckGadgetUp:    btst        #IDCMP_GADGETUP_B3,D2
  2073.         beq        CheckRefresh
  2074.  
  2075.         move.w        gg_GadgetID(A2),D2
  2076.  
  2077.         cmp.b        #5,D2
  2078.         bcc        1$           ; bhs
  2079.  
  2080. ;   Togglegadgets
  2081.         bchg        D2,_CxHandlerData+ssd_Options(A4)
  2082.         bra        NextMessage
  2083.  
  2084. 1$        bne        CheckButtons
  2085.  
  2086. ;   Hotkey
  2087.         lea        -ix_SIZEOF(SP),SP
  2088.         move.b        #IX_VERSION,(SP)       ; Don't know if this is needed
  2089.         move.l        _CxBase(A4),A6
  2090.         move.l        gg_SpecialInfo(A2),A0
  2091.         move.l        si_Buffer(A0),A3
  2092.  
  2093.         move.l        A3,A0
  2094.         move.l        SP,A1
  2095.         libcall     ParseIX        ; (A0=description,A1=ix)
  2096.  
  2097.         tst.l        D0
  2098.         bne        WrongHotKey
  2099.  
  2100.         move.l        _HotKeyFilterCxObj(A4),A0
  2101.         move.l        SP,A1
  2102.         libcall     SetFilterIX     ; (A0=filter,A1=ix)
  2103.  
  2104. ;   Copy the string to the hotkeybuffer
  2105.         lea        _HotKeyString(A4),A0
  2106. 2$        move.b        (A3)+,(A0)+
  2107.         bne        2$
  2108.         bra        HotKeyDone
  2109.  
  2110. WrongHotKey:    move.l        A2,-(SP)
  2111.         move.l        _IntuitionBase(A4),A6
  2112.         move.l        A5,A0
  2113.         lea        HotKeyReq(PC),A1
  2114.         sub.l        A2,A2
  2115.         sub.l        A3,A3
  2116.         libcall     EasyRequestArgs    ; (A0=window,A1=easyStruct,A2=idcmpPtr,A3=args)
  2117.  
  2118.         move.l        (SP)+,A2
  2119.  
  2120.         tst.l        D0
  2121.         bne        ChangeHotKey
  2122.  
  2123.         move.l        _GadToolsBase(A4),A6
  2124.         lea        SetStringTags(PC),A3
  2125.         lea        _HotKeyString(A4),A0
  2126.         move.l        A0,4(A3)
  2127.         move.l        A2,A0
  2128.         move.l        A5,A1
  2129.         sub.l        A2,A2
  2130.         libcall     GT_SetGadgetAttrsA ; (A0=gad,A1=win,A2=req,A3=taglist)
  2131.  
  2132.         bra        HotKeyDone
  2133.  
  2134. ChangeHotKey:    move.l        A2,A0
  2135.         move.l        A5,A1
  2136.         sub.l        A2,A2
  2137.         libcall     ActivateGadget    ; (A0=gadgets,A1=window,A2=requester)
  2138.  
  2139. HotKeyDone:    lea        ix_SIZEOF(SP),SP
  2140.         bra        NextMessage
  2141.  
  2142. CheckRefresh:    btst        #IDCMP_REFRESHWINDOW_B3,D2
  2143.         beq        NextMessage
  2144.  
  2145.         move.l        A5,A0
  2146.         libcall     GT_BeginRefresh    ; (A0=win)
  2147.  
  2148.         move.l        A5,A0
  2149.         moveq.l     #TRUE,D0
  2150.         libcall     GT_EndRefresh    ; (A0=win,D0=complete)
  2151.  
  2152.         bra        NextMessage
  2153.  
  2154. NoMoreMessages: move.l        D4,D0
  2155.         movem.l     (SP)+,D2-D4/A2-A3/A5-A6
  2156.         rts
  2157.  
  2158.  
  2159. ;***************************************************
  2160. ;* VOID CloseOptWindow(VOID) - close option window *
  2161. ;***************************************************
  2162. @CloseOptWindow:
  2163.         move.l        A2,-(SP)
  2164.         move.l        A6,-(SP)
  2165.  
  2166.         lea        WindowTags(PC),A2
  2167.  
  2168. ;    Remember position of window
  2169.         move.l        _OptWindow(A4),A0
  2170.         move.w        wd_LeftEdge(A0),wtag_Left+2(A2)
  2171.         move.w        wd_TopEdge(A0),wtag_Top+2(A2)
  2172.  
  2173.         move.l        _IntuitionBase(A4),A6
  2174.         libcall     CloseWindow     ; (A0=window)
  2175.  
  2176.         move.l        _GadToolsBase(A4),A6
  2177.         move.l        wtag_Gadgets(A2),A0
  2178.         libcall     FreeGadgets     ; (A0=gad)
  2179.  
  2180.         move.l        _VisualInfo(A4),A0
  2181.         libcall     FreeVisualInfo    ; (A0=vi)
  2182.  
  2183.         move.l        A6,A1        ; GadToolsBase
  2184.         move.l        _ExecBase(A4),A6
  2185.         libcall     CloseLibrary    ; (A1=library)
  2186.  
  2187.         move.l        _IntuitionBase(A4),A6
  2188.         move.l        wtag_PubScreen(A2),A1
  2189.         sub.l        A0,A0
  2190.         libcall     UnlockPubScreen    ; (A0=name,A1=screen)
  2191.  
  2192.         move.l        (SP)+,A6
  2193.         move.l        (SP)+,A2
  2194.         rts
  2195.  
  2196. ;************* S T R I N G   C O N S T A N T S ***************
  2197.         even
  2198. VERSIONSTRING:    dc.b        '$VER: PopUpMenu 5.0 (4-Okt-92)',0
  2199.         even
  2200. CXNAME:     dc.b        'PopUpMenu',0
  2201.         even
  2202. CXTITLE:    dc.b        'PopUpMenu 5.0 ',$a9,'1992 Martin Adrian',0
  2203.         even
  2204. CXDESCRIPTION:    dc.b        'Pop-up menus under mousepointer',0
  2205.         even
  2206. DOSNAME     dc.b        'dos.library',0
  2207.         even
  2208. INTUITIONNAME:    dc.b        'intuition.library',0
  2209.         even
  2210. GFXNAME:    dc.b        'graphics.library',0
  2211.         even
  2212. LAYERSNAME:    dc.b        'layers.library',0
  2213.         even
  2214. COMMODITYNAME:    dc.b        'commodities.library',0
  2215.         even
  2216. ICONNAME    dc.b        'icon.library',0
  2217.         even
  2218. GADTOOLSNAME:    dc.b        'gadtools.library',0
  2219.         even
  2220. IFFNAME     dc.b        'iffparse.library',0
  2221.         even
  2222. TIMERNAME:    dc.b        'timer.device',0
  2223.         even
  2224. ICNTRLFILENAME: dc.b        'ENV:sys/icontrol.prefs',0
  2225.         even
  2226. DEFAULTHOTKEY:    dc.b        'control alt p',0
  2227.         even
  2228. TEMPLATETEXT:    dc.b        'CLICKMENUS/S,SHOWSINGLE/S,CENTERITEMS/S,POPWITHQUAL/S,'
  2229.         dc.b        'CX_POPUP/S,CX_POPKEY/K,CX_PRIORITY/K/N',0
  2230.         even
  2231. ARG_CLICK:    dc.b        'CLICKMENUS',0
  2232.         even
  2233. ARG_SHOW:    dc.b        'SHOWSINGLE',0
  2234.         even
  2235. ARG_CENTER:    dc.b        'CENTERITEMS',0
  2236.         even
  2237. ARG_POPWITH:    dc.b        'POPWITHQUAL',0
  2238.         even
  2239. ARG_CXPOPUP:    dc.b        'CX_POPUP',0
  2240.         even
  2241. ARG_CXPOPKEY:    dc.b        'CX_POPKEY',0
  2242.         even
  2243. ARG_CXPRI:    dc.b        'CX_PRIORITY',0
  2244.         even
  2245. YESTEXT:    dc.b        'YES',0
  2246.         even
  2247. CLICKTEXT:    dc.b        '"_Click" menus',0
  2248.         even
  2249. SINGLETEXT:    dc.b        '_Show single menu',0
  2250.         even
  2251. CENTEREDTEXT:    dc.b        'Center menu_items',0
  2252.         even
  2253. WITHTEXT:    dc.b        '_with qualifier',0
  2254.         even
  2255. WITHOUTTEXT:    dc.b        'with_out qualifier',0
  2256.         even
  2257. HOTKEYTEXT:    dc.b        '_Hotkey',0
  2258.         even
  2259. KILLTEXT:    dc.b        '_Kill',0
  2260.         even
  2261. HIDETEXT:    dc.b        'Hide',0
  2262.         even
  2263. TEXTTEXT:    dc.b        'Pop-up menus',0
  2264.         even
  2265. WINDOWTITLE:    dc.b        'PopUpMenu 5.0',0
  2266.         even
  2267. EASYWINNAME:    equ        CXNAME
  2268.         even
  2269. EASYTEXT:    dc.b        'Invalid hotkey specification!',0
  2270.         even
  2271. EASYGADGETS:    dc.b        'Try again|Cancel',0
  2272.         even
  2273. TOPAZNAME:    dc.b        'topaz.font',0
  2274.         cnop        0,4
  2275.  
  2276. ;*************** T A G S **********************
  2277. StringTags:    dc.l        GTST_String,0    ; filled in
  2278.         dc.l        GTST_MaxChars,HOTKEYBUFLENGTH
  2279.         dc.l        GA_TabCycle,FALSE
  2280. ButtonTags:    dc.l        GT_Underscore,'_'
  2281. TagDone:    dc.l        TAG_DONE
  2282.  
  2283. SetStringTags:    dc.l        GTST_String,0    ; filled in
  2284.         dc.l        TAG_DONE
  2285.  
  2286. CheckBoxTags:    dc.l        GT_Underscore,'_'
  2287. CheckedTags:    dc.l        GTCB_Checked,0    ; filled in
  2288.         dc.l        TAG_DONE
  2289.  
  2290. WindowTags:
  2291. WLeft:        dc.l        WA_Left,154
  2292. WTop:        dc.l        WA_Top,62
  2293.         dc.l        WA_InnerWidth,290
  2294.         dc.l        WA_InnerHeight,98
  2295.         dc.l        WA_AutoAdjust,TRUE
  2296.         dc.l        WA_IDCMP,IDCMP_GADGETUP!IDCMP_CLOSEWINDOW!IDCMP_VANILLAKEY!IDCMP_REFRESHWINDOW
  2297.         dc.l        WA_Flags,WFLG_DRAGBAR!WFLG_DEPTHGADGET!WFLG_CLOSEGADGET!WFLG_SIMPLE_REFRESH!WFLG_ACTIVATE!WFLG_RMBTRAP
  2298. WGad:        dc.l        WA_Gadgets,0    ; filled in
  2299.         dc.l        WA_Title,WINDOWTITLE
  2300. WPub:        dc.l        WA_PubScreen,0    ; filled in
  2301.         dc.l        TAG_DONE
  2302.  
  2303. wtag_Left:    equ        (WLeft-WindowTags)+4
  2304. wtag_Top:    equ        (WTop-WindowTags)+4
  2305. wtag_Gadgets:    equ        (WGad-WindowTags)+4
  2306. wtag_PubScreen: equ        (WPub-WindowTags)+4
  2307.  
  2308. ;**************** T A B L E S ******************
  2309. CXCMDCOMMANDS:    dc.b        CXCMD_DISABLE,DISABLE_F!DISAPPEAR_F
  2310.         dc.b        CXCMD_ENABLE,ENABLE_F
  2311.         dc.b        CXCMD_APPEAR,APPEAR_F!ENABLE_F
  2312.         dc.b        CXCMD_UNIQUE,APPEAR_F!ENABLE_F
  2313.         dc.b        CXCMD_DISAPPEAR,DISAPPEAR_F
  2314.         dc.b        CXCMD_KILL,QUIT_F!DISAPPEAR_F!DISABLE_F
  2315. NoOfCommands:    equ        (*-CXCMDCOMMANDS)/2
  2316.         even
  2317.  
  2318. KeyData:    dc.b        'c',0   ; Clickmenus
  2319.         dc.b        'C',0
  2320.         dc.b        's',1   ; single menu
  2321.         dc.b        'S',1
  2322.         dc.b        'i',2   ; centered items
  2323.         dc.b        'I',2
  2324.         dc.b        'w',3   ; with qualifier
  2325.         dc.b        'W',3
  2326.         dc.b        'o',4   ; without qualifier
  2327.         dc.b        'O',4
  2328.         dc.b        'h',5   ; hotkey
  2329.         dc.b        'H',5
  2330.         dc.b        'k',6   ; Kill
  2331.         dc.b        'K',6
  2332.         dc.b        13,7    ; enter (hide)
  2333.         dc.b        27,7    ; Esc   (hide)
  2334. NoOfKeys:    equ        (*-KeyData)/2
  2335.         cnop        0,4
  2336.  
  2337. ;*************** C O N S T A N T S *************************
  2338. BrokerData:    dc.b        NB_VERSION,0        ; nb_Version, pad
  2339.         dc.l        CXNAME            ; nb_Name
  2340.         dc.l        CXTITLE            ; nb_Title
  2341.         dc.l        CXDESCRIPTION        ; nb_Descr
  2342.         dc.w        NBU_UNIQUE!NBU_NOTIFY   ; nb_Unique
  2343.         dc.w        COF_SHOW_HIDE        ; nb_Flags
  2344.         dc.b        0,0             ; nb_Pri, pad
  2345.         dc.l        0                ; nb_Port
  2346.         dc.w        0                ; nb_ReservedChannel
  2347.  
  2348. NotifyData:    dc.l        ICNTRLFILENAME    ; nr_Name
  2349.         dc.l        0            ; nr_FullName
  2350.         dc.l        0            ; nr_UserData
  2351.         dc.l        NRF_SEND_SIGNAL    ; nr_Flags
  2352.         dc.l        0            ; nr_Port | nr_Task
  2353.         dc.b        0            ; nr_SignalNum
  2354.         dc.b        0,0,0        ; nr_Pad
  2355.         dc.l        0,0,0,0        ; nr_Reserved
  2356.         dc.l        0            ; nr_MsgCount
  2357.         dc.l        0            ; nr_Handler
  2358.  
  2359. DefaultArgs:    dc.l        FALSE        ; arg_ClickMenus
  2360.         dc.l        FALSE        ; arg_ShowSingle
  2361.         dc.l        FALSE        ; arg_CenterItems
  2362.         dc.l        FALSE        ; arg_PopWithQual
  2363.         dc.l        FALSE        ; arg_PopUp
  2364.         dc.l        DEFAULTHOTKEY    ; arg_PopKey
  2365.         dc.l        Priority        ; arg_Pri
  2366.  
  2367. Topaz8Font:    dc.l        TOPAZNAME        ; ta_Name
  2368.         dc.w        8            ; ta_YSize
  2369.         dc.b        FS_NORMAL        ; ta_Style
  2370.         dc.b        FPF_ROMFONT     ; ta_Flags
  2371.  
  2372. HotKeyReq:    dc.l        es_SIZEOF        ; es_StructSize
  2373.         dc.l        0            ; es_Flags
  2374.         dc.l        EASYWINNAME     ; es_Title
  2375.         dc.l        EASYTEXT        ; es_TextFormat
  2376.         dc.l        EASYGADGETS     ; es_GadgetFormat
  2377.  
  2378. ;******************** V A R I A B L E S ***********************
  2379. ;  Used in the new intuition functions
  2380. OldClearMenuStrip:
  2381.         dc.l        0
  2382. OldOnMenu:    dc.l        0
  2383. OldOffMenu:    dc.l        0
  2384.  
  2385. ;  Used in the inputhandler
  2386. CxBase:     dc.l        0
  2387. IBase:        dc.l        0
  2388.  
  2389. ;  Used in ParseArgs
  2390. Priority    dc.l        0        ; deafult priority = 0
  2391.  
  2392. PopUpSemaphore: ds.b        SS_SIZE    ; placed here to reach with (PC)
  2393.         end
  2394.  
  2395.  
  2396.